Opened 5 years ago
Closed 5 years ago
#31553 closed Uncategorized (needsinfo)
Incorrect query for inline admin when the parent is a proxy model
Reported by: | Adam Duren | Owned by: | nobody |
---|---|---|---|
Component: | contrib.admin | Version: | 3.0 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Unreviewed | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
In our application we have a ModelAdmin
which displays all rows and a special ModelAdmin
which displays a subset of data available on the table (filtered rows) via the use of ProxyModel. The ModelAdmin
contains an inline to a related model.
We noticed that as our related table grew the time it took to render the one using a proxy model increased drastically. The non-proxy model detail page loads in sub-second where as the proxy model detail page takes over a minute.
Upon further inspection we discovered through the use of django-debug-toolbar
that the query which was being issued for the proxy model did not filter the related objects by the foreign key but instead retrieves all objects from the database.
Below is an example which will reproduce the issue. You can easily verify by creating two users. Create 100K notifications and assign them to User A. Click on the detail for User B and observe that User B takes just as long as User A to load only when using the Proxy model.
# models.py class User(models.Model): name = models.CharField() class UserProxy(User) class Meta: proxy = True class Notification(models.Model): user = models.ForeignKey("Person", models.CASCADE) text = models.CharField() # admin.py class NotificationAdmin(admin.TabularInline): model = Notification """ Query for will be: SELECT * FROM "app_notification" WHERE app_notification"."user_id" = 'd0b44931-2d8d-4668-a74b-38b83ba9abf4'::uuid """ class UserAdmin(admin.ModelAdmin): model = User """ Query for will be: SELECT * FROM "app_notification" """ class UserProxyAdmin(admin.ModelAdmin): model = UserProxy
Can you upload a sample project showing this in full please?
I suspect that this is because it's rendering the select widget for the form, which is the expected bahaviour if you're not using an autocomplete or raw_id field.