Создание модели с полем many-to-many и коэфициентами
Представим, что мы хотим создать базу данных рецептов блюд. Для этого мы создаем в models класс (например class DishModel) и задаем соотношение many-to-many с классом ингридиентов (class IngredientsModel). Но вот тут встает вопрос... Таким образом мы определим только список ингредиентов, но не кол-во, которое нужно добавлять в конечное блюдо.
Вопрос, как правильнее всего было определить поле class DishModel, чтобы хранить связку ингредиент + кол-во?
PS Читал про MultiValueField, но оно для форм. Есть ли аналог для моделей?
PSS Задать соответствующее поле в class IngredientsModel, логически не правильно, потому как кол-во ингредиента это именно информация про блюдо, а не ингредиент. Ингредиенты могут использоваться во многих блюдах.
Ответы (1 шт):
Вот такой вариант предложили. И он вроде работает, хотя я пока не до конца разобрался в механике. Если возникнут альтернативные идеи, или желание объяснить детали работы указанного кода, прошу в себе не держать.
You can define these in a through= model [Django-doc]:
class Ingredient(models.Model):
name = models.CharField(max_length=128, unique=True)
def __str__(self):
return self.name
class Dish(models.Model):
name = models.CharField(max_length=128, unique=True)
ingredients = models.ManyToManyField(
Ingredient, through='DishIngredient', related_name='dishes'
)
def __str__(self):
return self.name
class DishIngredient(models.Model):
dish = models.ForeignKey(Dish, on_delete=models.CASCADE)
ingredient = models.ForeignKey(Ingredient, on_delete=models.CASCADE)
quantity = models.IntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=('dish', 'ingredient'),
name='ingredient_once_per_dish'
)
]
we can then for a dish for example get the DishIngredients and thus print the ingredients with their quantity:
dish = # some_dish
for ingredient in dish.dishingredient_set.select_related('ingredient'):
print(f'{ingredient.quantity} {ingredient.ingredient}')