#16714: Can't filter by a related object's field called 'year', 'month' or 'day'
-------------------------------------+-------------------------------------
Reporter: Clueless | Owner: nobody
Type: Bug | Status: new
Milestone: | Component: Database layer
Version: 1.3 | (models, ORM)
Resolution: | Severity: Normal
Triage Stage: Accepted | Keywords:
Needs documentation: 0 | Has patch: 0
Patch needs improvement: 0 | Needs tests: 0
UI/UX: 0 | Easy pickings: 0
-------------------------------------+-------------------------------------
Changes (by julien):
* component: contrib.admin => Database layer (models, ORM)
* severity: Release blocker => Normal
Old description:
> 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.
New description:
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.
--
Comment:
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.
--
Ticket URL: <https://code.djangoproject.com/ticket/16714#comment:4>
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 post to this group, send email to [email protected].
To unsubscribe from this group, send email to
[email protected].
For more options, visit this group at
http://groups.google.com/group/django-updates?hl=en.