Django-native/ORM подход к самостоятельному присоединению
Пытаюсь настроить Django-native запрос, который захватывает все строки/отношения, когда он появляется на другой стороне отношения "многие ко многим".
Я могу объяснить на примере:
# Django models
class Ingredient:
id = ...
name = ...
...
class Dish:
id = ...
name = ...
...
class IngredientToDish
# this is a many to many relationship
ingredient_id = models.ForeignKey("Ingredient", ...)
dish_id = models.ForeignKey("Dish", ...)
...
Хотелось бы получить Django-нативный способ: "Для каждого блюда, в котором используется помидор, найдите все ингредиенты, которые в нем используются". Ищу список строк, который выглядит примерно так:
(cheese_id, pizza_id)
(sausage_id, pizza_id)
(tomato_id, pizza_id)
(cucumber_id, salad_id)
(tomato_id, salad_id)
Я хотел бы хранить их в одном запросе к БД, для оптимизации. В SQL это был бы простой JOIN с самим собой (IngredientToDish
таблица), но я не смог найти, каким должен быть обычный подход в Django... Скорее всего, используется какая-то форма select_related
, но я не смог заставить ее работать; я думаю, часть причины в том, что я не смог кратко выразить проблему в словах, чтобы найти нужную документацию во время исследования.
Любая помощь будет принята с благодарностью... спасибо!!!
Вы можете .filter(…)
[Django-doc] с:
Ingredient.objects.filter(
ingredienttodish__dish_id__ingredienttodish__ingredient_id__name='Tomato'
)
Вы также можете добавить первичный ключ блюда, для которого это удерживается с:
from django.db.models import F
Ingredient.objects.filter(
ingredienttodish__dish_id__ingredienttodish__ingredient_id__name='Tomato'
).annotate(
dish_id=F('ingredienttodish__dish_id')
)
Объекты Ingredient
, возникающие в результате этого QuerySet
будут иметь дополнительный атрибут dish_id
, содержащий первичный ключ Dish
, для которого они были использованы.
Примечание: Обычно не добавляют суффикс
.…_id
к полюForeignKey
, так как Django автоматически добавит поле-"близнец" с суффиксом…_id
. Поэтому он должен бытьdish
, вместо.dish_id