#28262: Using lookup with autocreated fields crashes django admin
-------------------------------------+-------------------------------------
Reporter: Michal Dabski | Owner: nobody
Type: Bug | Status: new
Component: contrib.admin | Version: 1.11
Severity: Normal | Resolution:
Keywords: | Triage Stage:
admin,lookup_allowed | Unreviewed
Has patch: 0 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 0
Easy pickings: 0 | UI/UX: 0
-------------------------------------+-------------------------------------
Changes (by Tim Graham):
* component: Uncategorized => contrib.admin
Old description:
> Consider the following models:
>
> {{{
> class AuditSession(Model):
> auditor = models.ForeignKey(User)
>
> class Institution(BaseModel):
> name = models.CharField(max_length=100)
>
> class Auditor(BaseModel):
> user = models.OneToOneField(User)
> institution = models.ForeignKey(Institution, null=True, blank=True)
> }}}
>
> And the following filter in audit session admin:
> {{{
> class AuditSessionAdmin(ModelAdmin):
> list_filter = (
> ('auditor__auditor__institution'),
> )
> }}}
>
> As of Django version 1.9 up to the latest release 1.11.1, the above
> lookup will raise server error when used by raising
> DisallowedModelAdminLookup (Filtering by
> auditor__auditor__institution__id__exact not allowed). This is because
> the lookup uses reverse relation between User and Auditor model.
>
> This lookup passes checks and only crashes when user tries to use the
> filter. I could not find the reasoning behind the implementation of
> lookup_allowed and why it would forbid using reverse relations. Nor could
> I find any documentation for this change in 1.9 release notes.
> I have recently upgraded from django 1.8 where this lookup worked
> perfectly fine.
New description:
Consider the following models:
{{{
class AuditSession(Model):
auditor = models.ForeignKey(User)
class Institution(BaseModel):
name = models.CharField(max_length=100)
class Auditor(BaseModel):
user = models.OneToOneField(User)
institution = models.ForeignKey(Institution, null=True, blank=True)
}}}
And the following filter in audit session admin:
{{{
class AuditSessionAdmin(ModelAdmin):
list_filter = (
('auditor__auditor__institution'),
)
}}}
As of Django version 1.9 up to the latest release 1.11.1, the above lookup
will raise server error when used by raising `DisallowedModelAdminLookup
(Filtering by auditor__auditor__institution__id__exact not allowed)`. This
is because the lookup uses reverse relation between User and Auditor
model.
This lookup passes checks and only crashes when user tries to use the
filter. I could not find the reasoning behind the implementation of
lookup_allowed and why it would forbid using reverse relations. Nor could
I find any documentation for this change in 1.9 release notes.
I have recently upgraded from django 1.8 where this lookup worked
perfectly fine.
--
Comment:
I can reproduce the issue with some caveats. I used `models.Model` instead
of `BaseModel` as you didn't provide a definition for that. I'm not sure
if that difference matters.
I bisected the behavior change to c2e70f02653519db3a49cd48f5158ccad7434d25
which is odd because that commit shouldn't change behavior. However,
before that commit (on 1.8), I get the error `(admin.E116) The value of
'list_filter[0]' refers to 'auditor__auditor__institution', which does not
refer to a Field.` Afterward that commit, I see the
`DisallowedModelAdminLookup` exception in this ticket's description.
--
Ticket URL: <https://code.djangoproject.com/ticket/28262#comment:1>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
--
You received this message because you are subscribed to the Google Groups
"Django updates" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
To post to this group, send email to [email protected].
To view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/064.ccfeb8d739b3acf1b9f65480d12de5b5%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.