Formatting many-to-many built-in models introduced by django admin

I have 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 relevant products as a beautiful table (of product fields) on the Invoice page in admin and be able to link to individual relevant product pages.

My first thought was to use the built-in admin, but django used a selection window widget for each related product. This is not related to the Product pages, and since I have thousands of products, and each checkbox independently loads all the product names, it quickly becomes unreasonably slow.

So, I turned to using ModelAdmin.filter_horizontal, as suggested here , which used one instance of another widget, where you have a list of all products and another list of related products, and you can add / remove products in a later one from the previous ones. This solved the slowness, but it still does not display the corresponding Product fields, and it is not related.

So what should I do? change settings? to override ModelForms? I googled around and couldn't find any example of such code ...

+4
source share
2 answers

This may not be what you expect, but I would introduce an InvoiceItem model that will link Invoice to Product. So you should have 2x 1: n instead of the m: n relationship. Then use the built-in custom form for InvoiceItem and raw_id_fields in this form to select the product.

In the InvoiceItem form, you can add readonly fields that will display the values ​​you need to display. You will need to provide data for these fields in the init form by reading them from an InvoiceItem instance. Or can you also get raw_id_field from the widget and add some additional data from the product model in the visualization method of this widget?

0
source

This is an old question, but I contacted him today.

Here you can find the answer - https://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/

The code:

 class MyAdmin(admin.TabularInline): fields = 'myfield', def formfield_for_dbfield(self, db_field, **kwargs): formfield = super(MyAdmin, self).formfield_for_dbfield(db_field, **kwargs) if db_field.name == 'myfield': # dirty trick so queryset is evaluated and cached in .choices formfield.choices = formfield.choices return formfield 

This can shorten the wait time from about 5 minutes to about 15 seconds.

0
source

Source: https://habr.com/ru/post/1310906/


All Articles