Поле модели для хранения упорядоченного списка ForeignKeys с дубликатами
У меня есть две модели A и B, и B хотел бы хранить упорядоченный список As, который может содержать дубликаты.
class A(models.Model):
...
class B(models.Model):
As = models.OrderedOneToManyWithDuplicatesField(A)
Где OrderedOneToManyWithDuplicatesField
- мифический.
Я представляю, что это может быть ManyToManyField
с пользовательской сквозной моделью, которая хранит a и ключ упорядочивания, но не уверен, поддерживает ли это и как одно и то же A, появляющееся больше, чем одно в данном B.As
.
class A(models.Model):
...
class B(models.Model):
As = models.ManyToManyField(A, through=A_List)
class A_List(models.Model):
A = models.ForeignKey(A)
B = models.ForeignKey(B)
index = models.PositiveIntegerField()
Я полагаю, что пока не нашел никакой документации, четко указывающей на это, и не нашел времени, чтобы проверить это (что я сделаю), и мне интересно, есть ли у кого-нибудь опыт, которым можно поделиться в промежутке.
Полагаю, вопрос сводится к тому, может ли A_list
содержать несколько строк, имеющих одинаковые A и B, но разный индекс. Что в свою очередь может сводиться к:
- Как Django ключает эту модель (если она имеет независимый
AutoField
первичный ключ, неявный или явный), например. То есть, A и B не являются вместе уникальным ключом. - Есть ли у менеджера(ов) какие-либо встроенные предпосылки об уникальности сквозной таблицы, которые нарушаются. Это сложнее установить с помощью базового эмпирического теста и может потребовать некоторого обзора кода или знаний. .
В любом случае, я бы хотел в конечном итоге иметь свойство или метод на B, который просто возвращает мне упорядоченный список As (включая любые дубликаты) для последующего использования.
Далее, я представляю, что это имеет непреднамеренный (и, возможно, нежелательный, но не сильно беспокоящий) эффект предоставления A доступа к списку B, в котором он появляется под B.As.
Если вы хотите хранить упорядоченный список ForeignKeys, допускающий дубликаты, вы можете использовать поле ManyToManyField в Django. Это поле используется для представления отношений "многие-ко-многим" между двумя моделями. Вот пример:
from django.db import models
class Item(models.Model):
# Other fields here...
pass
class Order(models.Model):
items = models.ManyToManyField(Item, related_name='orders')
# Other fields here...
pass
В этом примере модель Order имеет поле ManyToManyField под названием items, которое представляет собой отношение "многие-ко-многим" с моделью Item. Это означает, что объект Item может быть связан с несколькими объектами Order, а Order может иметь несколько объектов Item, связанных с ним. Кроме того, поле ManyToManyField позволяет дублировать объекты Item в одном заказе.
Вы можете получить доступ к списку объектов Item, связанных с объектом Order, используя атрибут items. Например:
my_order = Order.objects.first()
my_order_items = my_order.items.all()
Это вернет QuerySet объектов Item, связанных с объектом заказа my_order.
Помните, что поле ManyToManyField не хранит порядок объектов Item в списке. Если вам нужно поддерживать порядок элементов в списке, вы можете использовать сквозную модель, чтобы указать дополнительную модель, которая представляет отношения между моделями Order и Item, и добавить в эту модель поле PositiveIntegerField для хранения порядка объектов Item. Вот пример:
from django.db import models
class Item(models.Model):
# Other fields here...
pass
class Order(models.Model):
# Other fields here...
pass
class OrderItem(models.Model):
order = models.ForeignKey(Order, on_delete=models.CASCADE, related_name='order_items')
item = models.ForeignKey(Item, on_delete=models.CASCADE, related_name='order_items')
order_index = models.PositiveIntegerField()
class Order(models.Model):
items = models.ManyToManyField(Item, through='OrderItem', related_name='orders')
В этом примере модель OrderItem представляет отношения между моделями Order и Item и имеет поле ForeignKey для каждой модели, а также поле PositiveIntegerField под названием order_index для хранения порядка объектов Item в списке. Модель Order теперь имеет поле ManyToManyField под названием items, которое использует модель OrderItem в качестве "сквозной" модели, позволяя вам получить доступ к списку объектов Item, связанных с объектом Order, таким же образом, как и раньше, но теперь вы также можете получить доступ к полю order_index объектов OrderItem для определения порядка объектов Item в списке.
Например:
my_order = Order.objects.first()
my_order_items = my_order.items.all()