Django manytomany字段,如何检查80%子集/匹配?

dvc*_*dvc 7 python django manytomanyfield

我有一个带烹饪食谱的Django数据库.我想查询所有拥有至少80%成分的用户来制作食谱.我该如何实现这一目标?

或者我如何查询缺少配方的1种成分的用户?

models.py

class ingredient(models.Model):
    id = models.AutoField("id",max_length = 100, primary_key=True)
    name=models.CharField("Ingredient", max_length=100)

    def __unicode__ (self):
        return self.name

class user(models.Model):
    id = models.AutoField("id",max_length = 100, primary_key=True
    ingredient = models.ManyToManyField(ingredient,blank=True)

    def __unicode__ (self):
        return str(self.id)

class recipe(models.Model):
    id = models.AutoField("id", max_length=100, primary_key=True)
    recipe_ingredient = models.ManyToManyField(ingredient,related_name='recipe_ingredient',blank=True)

    def __unicode__ (self):
        return self.id
Run Code Online (Sandbox Code Playgroud)

Cha*_*arl 3

我将使用django-haystack为此,您可以为您的 job_opening模型设置一个索引并索引所有成分:

class JobOpeningIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    recipe_ingredient = indexes.MultiValueField()

    def prepare_recipe_ingredient(self, obj):
        return [i.name for i in obj.recipe_ingredient.all()]

    def get_model(self):
        return job_opening

    def index_queryset(self, using=None):
        return self.get_model().objects.all()
Run Code Online (Sandbox Code Playgroud)

创建索引后,您只需按成分或成分列表进行过滤,haystack 将返回符合搜索条件的所有对象,并按相关性排序。然后,您可以将 映射80%到相关性分数,并过滤掉相关性低于所需数量的项目。

SearchQuerySet().models(job_opening).filter(recipe_ingredient__in=['ingredient1', 'ingredient2', 'ingredient3'])
Run Code Online (Sandbox Code Playgroud)

编辑

阅读编辑后的问题后,我们基本上必须使用recipe我们使用过的地方job_opening。看起来你想找到相关的用户,而不是食谱。要实现此目的,您必须对用户模型而不是原始job_opening模型进行索引:

class UserIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    ingredient = indexes.MultiValueField()

    def prepare_ingredient(self, obj):
        return [i.name for i in obj.ingredient.all()]

    def get_model(self):
        return user

    def index_queryset(self, using=None):
        return self.get_model().objects.all()
Run Code Online (Sandbox Code Playgroud)

创建索引后,您可以像这样进行过滤:

myrecipe = recipe.objects.get(...)
SearchQuerySet().models(user).filter(ingredient__in=myrecipe.recipe_ingredient.all())
Run Code Online (Sandbox Code Playgroud)