django:在Drink数据库中按成分搜索

时间:2019-06-08 14:43:38

标签: python django filter

我想创建一个Django过滤器,该过滤器查找饮料中包含的成分。但是,没有其他成分存在,只有我输入的成分。

示例:

  • 饮料:杜松子酒滋补品
    成分:杜松子酒,滋补品
  • 饮料:威士忌可乐
    成分:威士忌可乐
  • 饮料:可乐朗姆酒
    成分:可乐朗姆酒

我承认我有可乐,杜松子酒和补品。

以下饮料应该回来:

  • 杜松子酒补品

朗姆可乐没有回来,因为我没有朗姆酒。

我如何在Django中做到这一点?我有一个数据库,名为TankAllocation。我在那里输入每个储罐的配料。

我尝试使用Django过滤器,但是那里没有正确的饮料。

也许我可以比较成分表和储罐表中成分的查询集并删除重复的条目,然后使用以下命令启动非等价查询:from django.db.models importQ。但是如何在以下位置删除重复的条目:查询集?对于新的过滤器查询,两个条目都应删除。

Models.py

from django.db import models

class Drink(models.Model):
    name = models.CharField(max_length=256, unique=True)
    description = models.TextField()
    image_path = models.ImageField(upload_to=".\images")
    slug = models.SlugField(unique=True)
    ingredient = models.ManyToManyField('Ingredient', through='IngredientRatio', related_name='mischung',)

    def __str__(self):
        return self.name

class Ingredient(models.Model):
    name = models.CharField(max_length=256, unique=True)
    alcohol = models.BooleanField()

    def __str__(self):
        return self.name

class IngredientRatio(models.Model):
    quantity = models.DecimalField(max_digits=4, decimal_places=2)
    ingredient = models.ForeignKey('Ingredient', on_delete=models.CASCADE)
    drink = models.ForeignKey('Drink', on_delete=models.CASCADE)

    def __str__(self):
        return "{0}: {1} : {2}".format(self.drink.name, self.ingredient.name, self.quantity)

class TankAllocation(models.Model):
    name = models.CharField(max_length=8, unique=True)
    allocation = models.ForeignKey('Ingredient', on_delete=models.CASCADE, default='NULL', related_name='ingredients')

    def __str__(self):
        return "{0}: {1}".format(self.allocation.name, self.name)


谢谢您的帮助,我在编程方面是个新手:)))

2 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解,但是这样的事情应该起作用:

ingredients = ['Cola', 'Gin', 'Tonic']
drinks = Drink.objects.filter(ingredient__name__in=ingredients).distinct()

答案 1 :(得分:0)

我现在找到了解决方案:)

import operator
from functools import reduce

from django.db.models import Q

from .models import Ingredient, TankAllocation, Drink


def drinkFilter():
    ingredient_list_nq = []
    ingredient_obj_list = Ingredient.objects.all()
    ingredients = [ingredient.name for ingredient in ingredient_obj_list]
    tanks = TankAllocation.objects.all()
    tank_ingredients = [tank.allocation.name for tank in tanks]
    for ingredient in ingredients:
        if ingredient not in tank_ingredients:
            ingredient_list_nq.append(ingredient)

    new_filter = []
    for ingredient in ingredient_list_nq:
        new_filter.append(~Q(ingredient__name=ingredient))
    print(new_filter)
    return new_filter

def get_drinks():
    filter = drinkFilter()
    return Drink.objects.filter(reduce(operator.and_, filter))