views:

38

answers:

1

I've got two django models (simplified):

class Product(models.Model):
    name  = models.TextField()
    price = models.IntegerField()

class Invoice(models.Model):
    company  = models.TextField()
    customer = models.TextField()
    products = models.ManyToManyField(Product)

I would like to see the relevant products as a nice table (of product fields) in an Invoice page in admin and be able to link to the individual respective Product pages.

My first thought was using the admin's inline - but django used a select box widget per related Product. This isn't linked to the Product pages, and also as I have thousands of products, and each select box independently downloads all the product names, it quickly becomes unreasonably slow.

So I turned to using ModelAdmin.filter_horizontal as suggested here, which used a single instance of a different widget, where you have a list of all Products and another list of related Products and you can add\remove products in the later from the former. This solved the slowness, but it still doesn't show the relevant Product fields, and it ain't linkable.

So, what should I do? tweak views? override ModelForms? I Googled around and couldn't find any example of such code...

A: 

Maybe it is not what you expect but I would introduce InvoiceItem model which would link Invoice to Product. So you would have 2x 1:n instead of m:n relation. Then use inline custom form for InvoiceItem and raw_id_fields in that form for Product choice.

In InvoiceItem form then you could add readonly fields that would display values you need to display. You will have to provide data for these fields in Form's init reading them from InvoiceItem instance. Or you could also derive from raw_id_field widget and in render method of this widget append some additional data from the product model?

Łukasz Korzybski