Many foreign keys - Django Admin

You have a SQL problem, adding that this model is working correctly, the problem is in ADMIN.

When I add only a few data to each table by pressing TYPE and PAGE in ADMIN , the page loads so slowly that it is set by debug_toolbar , and SQL takes 17 seconds for TYPE . When I tried PAGE , it gave me a timeout, my question is what is wrong with my model? Is it bad?

My goal is to:

http://www.example.com/audi/4doors/s4/sport/red/audi-url

Basically, all 6 URLs are dynamic, which I will indicate in each table, and they will be in the PAGE dropdown in others. What is the best way to do this or optimize a model?

Here is a screenshot of the TYPE page loading:

screenshot: http://cl.ly/image/2931040E0t35

Please help thanks

 from django.db import models class Client(models.Model): title = models.CharField(max_length=100, unique=True) def __unicode__(self): return self.title class Category(models.Model): client = models.ForeignKey(Client, to_field='title') title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Subcategory(models.Model): client = models.ForeignKey(Client, to_field='title') category = models.ForeignKey(Category, to_field='title') title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Project(models.Model): client = models.ForeignKey(Client, to_field='title') category = models.ForeignKey(Category, to_field='title') subcategory = models.ForeignKey(Subcategory, to_field='title') title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Type(models.Model): client = models.ForeignKey(Client, to_field='title') category = models.ForeignKey(Category, to_field='title') subcategory = models.ForeignKey(Subcategory, to_field='title') project = models.ForeignKey(Project, to_field='title') title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Page(models.Model): client = models.ForeignKey(Client, to_field='title') category = models.ForeignKey(Category, to_field='title') subcategory = models.ForeignKey(Subcategory, to_field='title') project = models.ForeignKey(Project, to_field='title') type = models.ForeignKey(Type, to_field='title') pageurl = models.CharField(max_length=200) 

It also turned out that when you delete foreign keys from admin.py from list_display it works quickly:

 class ClientAdmin(admin.ModelAdmin): list_display = ('title',) admin.site.register(Client, ClientAdmin) class CategoryAdmin(admin.ModelAdmin): list_display = ('client', 'title',) admin.site.register(Category, CategoryAdmin) class SubcategoryAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'title', ) admin.site.register(Subcategory, SubcategoryAdmin) class ProjectAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'subcategory', 'title', ) admin.site.register(Project, ProjectAdmin) class TypeAdmin(admin.ModelAdmin): list_display = ('client', 'title', ) admin.site.register(Type, TypeAdmin) class PageAdmin(admin.ModelAdmin): list_display = ('client', ) admin.site.register(Page, PageAdmin) 

FOREIGN KEYS can't be in list_display? How to optimize them?

Update:

 class Client(models.Model): title = models.CharField(max_length=100, unique=True, db_index=True) def __unicode__(self): return self.title class Category(models.Model): client = models.ForeignKey(Client) title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Subcategory(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Project(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Type(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) project = models.ForeignKey(Project) title = models.CharField(max_length=200, unique=True) def __unicode__(self): return self.title class Page(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) project = models.ForeignKey(Project) type = models.ForeignKey(Type) pageurl = models.CharField(max_length=200) 

UPDATE 2

 from django.db import models class Client(models.Model): title = models.CharField(max_length=100, primary_key=True) def __unicode__(self): return self.title class Category(models.Model): client = models.ForeignKey(Client) title = models.CharField(max_length=200, primary_key=True) def __unicode__(self): return self.title class Subcategory(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) title = models.CharField(max_length=200, primary_key=True) def __unicode__(self): return self.title class Project(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) title = models.CharField(max_length=200, primary_key=True) def __unicode__(self): return self.title class Type(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) project = models.ForeignKey(Project) title = models.CharField(max_length=200, primary_key=True) def __unicode__(self): return self.title class Page(models.Model): client = models.ForeignKey(Client) category = models.ForeignKey(Category) subcategory = models.ForeignKey(Subcategory) project = models.ForeignKey(Project) type = models.ForeignKey(Type) pageurl = models.CharField(max_length=200) 

UPDATE 3 - ADMIN.PY

 class ClientAdmin(admin.ModelAdmin): list_display = ('title',) admin.site.register(Client, ClientAdmin) class CategoryAdmin(admin.ModelAdmin): list_display = ('client', 'title',) admin.site.register(Category, CategoryAdmin) class SubcategoryAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'title', ) admin.site.register(Subcategory, SubcategoryAdmin) class ProjectAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'subcategory', 'title', ) admin.site.register(Project, ProjectAdmin) class TypeAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'subcategory', 'project', 'title', ) admin.site.register(Type, TypeAdmin) class PageAdmin(admin.ModelAdmin): list_display = ('client', 'category', 'subcategory', 'project', 'type', 'pageurl', ) admin.site.register(Page, PageAdmin) 
+4
source share
2 answers

Instead, you can use the raw_id_fields django admin option.

 admin.site.register(Client) class CategoryAdmin(admin.ModelAdmin): raw_id_fields = ('client',) admin.site.register(Category, CategoryAdmin) class SubcategoryAdmin(admin.ModelAdmin): raw_id_fields = ('client', 'category') admin.site.register(Subcategory, SubcategoryAdmin) class ProjectAdmin(admin.ModelAdmin): raw_id_fields = ('client', 'category', 'subcategory') admin.site.register(Project, ProjectAdmin) class TypeAdmin(admin.ModelAdmin): raw_id_fields = ('client', 'category', 'subcategory', 'project') admin.site.register(Type, TypeAdmin) class PageAdmin(admin.ModelAdmin): raw_id_fields = ('client', 'category', 'subcategory', 'project', 'type') admin.site.register(Page, PageAdmin) 

this is the old onethis is new sql query

+4
source

Hmmm, I'm not sure if this matches 100% (since I use FK in list_display and list_editable). I get acceleration with the trick described here: http://blog.ionelmc.ro/2012/01/19/tweaks-for-making-django-admin-faster/

It seems that the selection is evaluated for each row (esp when using list_editable for FK), so using formfield_for_dbfield you can cache the options as suggested in the link. This saves switching to db for rendering each popup menu / selection window for foreign_keys.

You can view the queries that are executed in the view if you enable the common mysql log (if you are using MySQL).

+1
source

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


All Articles