Opened 13 years ago
Last modified 13 years ago
#16714 closed Bug
Can't filter by a related object's field called 'year', 'month' or 'day' — at Version 4
Reported by: | Alex Ogier | Owned by: | nobody |
---|---|---|---|
Component: | Database layer (models, ORM) | Version: | 1.3 |
Severity: | Normal | Keywords: | |
Cc: | Triage Stage: | Accepted | |
Has patch: | no | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description (last modified by )
UPDATE: The problem was originally reported in the admin but it appears it is rather an issue with the ORM -- see discussion below.
If you have a SmallIntegerField on a model that is related via a foreign key then you can't use that field as an option in list_filter. Doing so gives you the correct distinct options in the list page sidebar, but if you try to select any of them you receive a 302 redirect to /?e=1, as if you had used an unexpected query-string parameter.
Here's a small example to try yourself:
# models.py from django.db import models class Rel(models.Model): year = models.SmallIntegerField(default=2010) class Src(models.Model): rel = models.ForeignKey(Rel) # admin.py from models import Rel, Src from django.contrib import admin class RelAdmin(admin.ModelAdmin): model = Rel list_filter = ('year',) admin.site.register(Rel, RelAdmin) class SrcAdmin(admin.ModelAdmin): model = Src list_filter = ('rel__year',) admin.site.register(Src, SrcAdmin)
I'm running Django 1.3, MySQL 5.5, on Arch Linux.
Change History (4)
follow-up: 2 comment:1 by , 13 years ago
Severity: | Normal → Release blocker |
---|---|
Triage Stage: | Unreviewed → Accepted |
comment:2 by , 13 years ago
Replying to julien:
I would think perhaps the lookup should be 'exact' instead of 'year'.
That's interesting, because that's not how things work with plain IntegerFields.
comment:3 by , 13 years ago
Interesting, indeed. I might be missing something fundamental but I'm puzzled as to why TypeErrors are raised in the following:
>>> Rel.objects.filter(year=u'2010') [<Rel: Rel object>] >>> Rel.objects.filter(year=2010) [<Rel: Rel object>] >>> Rel.objects.filter(year__exact=2010) [<Rel: Rel object>] >>> Src.objects.filter(rel__year__exact=2010) [<Src: Src object>] >>> Src.objects.filter(rel__year__exact=u'2010') [<Src: Src object>] >>> Src.objects.filter(rel__year=2010) ... TypeError: Related Field has invalid lookup: year >>> Src.objects.filter(rel__year=u'2010') ... TypeError: Related Field has invalid lookup: year
comment:4 by , 13 years ago
Component: | contrib.admin → Database layer (models, ORM) |
---|---|
Description: | modified (diff) |
Severity: | Release blocker → Normal |
Summary: | Can't list_filter across a relationship on a SmallIntegerField → Can't filter by a related object's field called 'year', 'month' or 'day' |
Some further investigation shows that the problem has nothing to do with the type of field (SmallIntegerField, CharField, ...) -- the issue is in fact with the *name* of the field. The same "TypeError: Related Field has invalid lookup: xxxx
" exception is raised for any fields named year
, month
or day
on the related model. There is obviously some sort of conflict with the date lookup system, although it seems strange that the RelatedField isn't more smart about it. It's also strange that this issue didn't surface for all those years as the use case is quite trivial...
There's still a regression with the way the admin changelist handles exceptions (the dev version crashes with a 500 instead of redirecting) and I've created a separate ticket for that: #16716.
Let's keep this ticket here to discuss the ORM issue. This is not a regression though, as it already existed at least in 1.3, so I'm removing the 'blocker' flag.
Hmm, the root cause of this seems like a problem not in the admin but deeper down in the ORM:
I would think perhaps the lookup should be 'exact' instead of 'year'. A separate ticket should probably be created for that. I'd like to hear from someone with more ORM-foo than me to confirm.
However, this highlights a regression in the admin, as the development version returns a 500 instead of redirecting with "?e=1".