Added fuzzy search function for matching against part names

This commit is contained in:
Oliver Walters 2019-05-11 10:36:24 +10:00
parent 343850c4f0
commit 1b8ca34ddb

View File

@ -24,6 +24,8 @@ from django.contrib.auth.models import User
from django.db.models.signals import pre_delete from django.db.models.signals import pre_delete
from django.dispatch import receiver from django.dispatch import receiver
from fuzzywuzzy import fuzz
from InvenTree import helpers from InvenTree import helpers
from InvenTree import validators from InvenTree import validators
from InvenTree.models import InvenTreeTree from InvenTree.models import InvenTreeTree
@ -88,8 +90,6 @@ def before_delete_part_category(sender, instance, using, **kwargs):
child.save() child.save()
# Function to automatically rename a part image on upload
# Format: part_pk.<img>
def rename_part_image(instance, filename): def rename_part_image(instance, filename):
""" Function for renaming a part image file """ Function for renaming a part image file
@ -116,6 +116,43 @@ def rename_part_image(instance, filename):
return os.path.join(base, fn) return os.path.join(base, fn)
def match_part_names(match, include_description=False, threshold=65, reverse=True):
""" Return a list of parts whose name matches the search term using fuzzy search.
Args:
match: Term to match against
include_description: Also search the part description (default = False)
threshold: Match percentage that must be exceeded (default = 65)
reverse: Ordering for search results (default = True - highest match is first)
Returns:
A sorted dict where each element contains the following key:value pairs:
- 'part' : The matched part
- 'ratio' : The matched ratio
"""
parts = Part.objects.all()
matches = []
for part in parts:
compare = part.name
if include_description:
compare += part.description
ratio = fuzz.partial_ratio(match, compare)
if ratio >= threshold:
matches.append({
'part': part,
'ratio': ratio
})
matches = sorted(matches, key=lambda item: item['ratio'], reverse=reverse)
return matches
class Part(models.Model): class Part(models.Model):
""" The Part object represents an abstract part, the 'concept' of an actual entity. """ The Part object represents an abstract part, the 'concept' of an actual entity.