django: поиск по ингредиентам в базе данных Drink - PullRequest
0 голосов
/ 08 июня 2019

Я хочу создать фильтр Django, который ищет ингредиенты, входящие в состав напитка. Однако никакие другие ингредиенты не могут присутствовать, только те, которые я ввожу.

Пример:

  • Напиток: Джин Тоник
    Ингредиенты: Джин Тоник
  • Напиток: Виски Кола
    Ингредиенты: Виски Кола
  • Напиток: ромовая кола
    Ингредиенты: ром, кола

Признаюсь, у меня есть кола, джин и тоник.

Следующие напитки должны вернуться:

  • Джин Тоник

Ромовая кола не возвращается, потому что у меня нет рома.

Как я могу сделать это в Django? У меня есть база данных звонков TankAllocation. Там я ввожу ингредиенты для каждого бака.

Я пробовал с фильтром Django, но там я не получаю правильные напитки.

Может быть, я могу сравнить набор запросов ингредиентов таблицы Ingredients и таблицы Tank и удалить дублирующиеся записи, а затем начать неравный запрос с помощью: из django.db.models import Q. Но как я могу удалить дублирующиеся записи в Querieset? обе записи должны быть удалены для нового фильтра запроса.

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 голосов
/ 09 июня 2019

Я нашел решение сейчас:)

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))
0 голосов
/ 08 июня 2019

Я не уверен, что полностью понимаю, но что-то вроде этого должно работать:

ingredients = ['Cola', 'Gin', 'Tonic']
drinks = Drink.objects.filter(ingredient__name__in=ingredients).distinct()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...