Django - Модели - Связывание моделей с другими моделями и наоборот
Я пытаюсь связать venues
с products
, которые они поставляют. Поставляемые продукты не являются уникальными для каждого заведения.
В результате Место 1 и Место 2 могут оба предоставить продукт A.
Результат, который я ищу, двоякий:
- Когда
Product
добавляется в базу данных, есть возможность связать его с существующимVenue
- Когда я рассматриваю конкретное место, я хотел бы иметь список всех продуктов, которые могут быть поставлены .
Я пробовал использовать Foreign Keys
и ManyToManyFields
, но это только добавляет все продукты, имеющиеся в базе данных, на все площадки, не оставляя выбора.
Вторая проблема, очевидно, заключается в обращении к Product
из модели Venue
. Если я ввожу в нее внешний ключ или любую форму отношения, Django расстраивается и говорит мне, что Product is not defined.
Я думал о создании третьей модели, которая могла бы объединить Venue
и Products
, но мне кажется, что должно быть что-то более сложное, что можно было бы сделать.
class Venue(models.Model):
name = models.CharField(verbose_name="Name",max_length=100, null=True, blank=True)
class Product(models.Model):
name = models.CharField('Product Name', max_length=120, null=True)
venue = models.ForeignKey(Venue, blank=True, related_name="venue", on_delete=models.CASCADE)
A ManyToManyField
на самом деле идеально подходит для того, что вы хотите сделать. Он связывает друг с другом только те объекты, для которых отношения были явно созданы, например, в админке или программно. Я не уверен, какое поведение вы сейчас получаете, но, возможно, страница документации по этой теме прояснит вам это. Вы можете определить свой ManyToManyField
либо на Product
, либо на Venue
.
Но сначала о второй проблеме: аргумент related_name
работает иначе, чем вы думаете: в вашей последней строке кода вы должны написать что-то вроде related_name="available_products"
, потому что related_name
становится именем атрибута ваших Venue
экземпляров , по которому вы можете получить доступ ко всем Product
объектам, которые были связаны с этим Venue
объектом, например, так: venue.available_products.all()
related_name
работает одинаково для ManyToManyField
и ForeignKey
, так что в целом, вы должны сделать что-то вроде:
class Venue(models.Model):
name = models.CharField(verbose_name="Name",max_length=100, blank=True)
class Product(models.Model):
name = models.CharField('Product Name', max_length=120, blank=True)
venues = models.ManyToManyField(Venue, blank=True, related_name="available_products")
(Примечание: Для CharField
s рекомендуется не устанавливать null=True
и вместо этого использовать только blank=True
, потому что в противном случае будет два различных варианта "нет данных", а именно Null и пустая строка. Подробности в docs.)