Фон
Я создал три модели Django - Inventory, SalesOrder и Invoice - для моделирования товаров в запасах, заказов на продажу для этих товаров и счетов-фактур для конкретного заказа на продажу. Каждый заказ на продажу может иметь несколько позиций, поэтому я использовал таблицу промежуточных соединений - SalesOrderItems
- используя аргумент through
для ManyToManyField
. Кроме того, частичное выставление счетов по заказам на продажу разрешено, поэтому я создал ForeignKey
в модели Invoice
, относящейся к модели SalesOrder
, чтобы конкретный заказ на продажу мог иметь несколько счетов-фактур.
Вот где я отклоняюсь от того, что я обычно видел. Вместо того, чтобы связывать модель Invoice
с моделью Item
через ManyToManyField
, я связал модель Invoice
с таблицей промежуточных соединений SalesOrderItem
через таблицу промежуточных соединений InvoiceItem
. Я сделал это, потому что это лучше моделирует реальность - наши счета-фактуры привязаны к заказам на продажу и могут включать в себя только те товары, которые связаны с этим заказом на продажу, в отличие от любого товара в запасах. Я признаю, что странно иметь промежуточную соединительную таблицу ManyToManyField
, связанную с промежуточной соединительной таблицей другого ManyToManyField
.
.
Вопросы
- Есть ли лучший способ смоделировать отношения, позволяя только элементам в счете-фактуре быть теми элементами, которые связаны с заказом на продажу счета-фактуры?
- Является ли модель правильным местом для включения логики ограничения позиций счета-фактуры только теми элементами, которые связаны с заказом на продажу счета-фактуры? IMO, ответ «да», учитывая, что [документация Django] [dj-model-doc] описывает модель как «единственный, окончательный источник данных о ваших данных».
- Как я могу ограничить варианты, доступные для
invoice_items
в модели Invoice
, до sales_order_items
модели SalesOrder
для этого конкретного Invoice
независимо от доступа к модели через страницы администратора или сформировать?
код
class Item(models.Model):
item_num = models.SlugField(unique=True)
default_price = models.DecimalField(max_digits=10, decimal_places=2,
blank=True, null=True)
class SalesOrderItem(models.Model):
item = models.ForeignKey(Item)
sales_order = models.ForeignKey('SalesOrder')
unit_price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
class SalesOrder(models.Model):
customer = models.ForeignKey(Party)
so_num = models.SlugField(max_length=40, unique=True)
sales_order_items = models.ManyToManyField(Item,
through=SalesOrderItem)
class InvoiceItem(models.Model):
item = models.ForeignKey(SalesOrderItem)
invoice = models.ForeignKey('Invoice')
unit_price = models.DecimalField(max_digits=10, decimal_places=2)
quantity = models.DecimalField(max_digits=10, decimal_places=4)
class Invoice(models.Model):
invoice_num = models.SlugField(max_length=25)
sales_order = models.ForeignKey(SalesOrder)
invoice_items = models.ManyToManyField(SalesOrderItem,
through='InvoiceItem')