Я хочу создать веб-интерфейс для базы данных рецептов, которая позволит пользователю искать список рецептов, которые можно готовить с ингредиентами, которые он предоставляет.
У меня есть следующие модели
class Ingredient(models.Model):
name = models.CharField(max_length=100, unique=True)
slug = models.SlugField(max_length=100, unique=True)
importancy = models.PositiveSmallIntegerField(default=4)
[…]
class Amount(models.Model):
recipe = models.ForeignKey('Recipe')
ingredient = models.ForeignKey(Ingredient)
[…]
class Recipe(models.Model):
name = models.CharField(max_length=100)
slug = models.SlugField()
instructions = models.TextField()
ingredients = models.ManyToManyField(Ingredient, through=Amount)
[…]
и запрос, который делает именно то, что я хочу: он получает все рецепты, чьи обязательные ингредиенты все содержатся в списке строк, которые предоставляет пользователь. Если он поставляет больше, чем нужно, это тоже нормально.
query = "SELECT *,
COUNT(amount.zutat_id) AS selected_count_ingredients,
(SELECT COUNT(*)
FROM amount
WHERE amount.recipe_id = amount.id)
AS count_ingredients
FROM amount LEFT OUTER JOIN amount
ON (recipe.id = recipe.recipe_id)
WHERE amount.ingredient_id IN (%s)
GROUP BY amount.id
HAVING count_ingredients=selected_count_ingredients" %
",".join([str(ingredient.id) for ingredient in ingredients])
recipes = Recipe.objects.raw(query)
Теперь я ищу способ, который не опирается на .raw()
, поскольку я хотел бы сделать это исключительно с помощью методов набора запросов Django.
Кроме того, было бы замечательно, если бы вы, ребята, знали способ включения важности ингредиента в поиск, чтобы рецепт все еще отображался в результате, даже если один из его ингредиентов (который имеет значение 0) не поставляется пользователем.