Background
I've created three Django models—Inventory, SalesOrder, and Invoice—to model items in inventory, sales orders for those items, and invoices for a particular sales order. Each sales order can have multiple items, so I've used an intermediary junction table—SalesOrderItems—using the through argument for the ManyToManyField. Also, partial billing of a sales orders is allowed, so I've created a ForeignKey in the Invoice model related to the SalesOrder model, so that a particular sales order can have multiple  invoices.
Here's where I deviate from what I've normally seen. Instead of relating the Invoice model to the Item model via a ManyToManyField, I've related the Invoice model to the SalesOrderItem intermediary junction table through the intermediary junction table InvoiceItem. I've done this because it better models reality—our invoices are tied to sales orders and can only include items that are tied to that sales order as opposed to any item in inventory. I will admit that it does seem strange having the intermediary junction table of a ManyToManyField relat开发者_JAVA技巧ed to the intermediary junction table of another ManyToManyField.
Questions
- Is there a better way to model the relationship of only allowing items on an invoice to be those items that are associated with the invoice's sales order?
- Is the model the correct place to include the logic to limit the invoice items to only those items that are associated with the invoice's sales order? IMO, the answer is "yes" given that the [Django documentation][dj-model-doc] describes a model as "the single, definitive source of data about your data."
- How can I limit the choices available for the invoice_itemsin theInvoicemodel to just thesales_order_itemsof theSalesOrdermodel for that particularInvoiceregardless of accessing the model via the admin pages or a form?
Code
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')
limit_choices_to only affects the admin pages. If you want to change the available choices in a normal ModelForm then you'll need to modify the queryset attribute of the form field.
 
         
                                         
                                         
                                         
                                        ![Interactive visualization of a graph in python [closed]](https://www.devze.com/res/2023/04-10/09/92d32fe8c0d22fb96bd6f6e8b7d1f457.gif) 
                                         
                                         
                                         
                                         加载中,请稍侯......
 加载中,请稍侯......
      
精彩评论