#12024 closed (fixed)
error with limit_choices_to with complex queries (Q object) and raw_id_fields
| Reported by: | anonymous | Owned by: | nobody |
|---|---|---|---|
| Component: | contrib.admin | Version: | 1.1 |
| Severity: | Keywords: | ||
| Cc: | Ryan Nowakowski | Triage Stage: | Accepted |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
hello
I have a model.py like this :
class secondaryGroup(models.Model):
id = models.AutoField(primary_key = True)
idGroup = models.ForeignKey(Group,db_column = 'idGroup',verbose_name = 'Groupe',limit_choices_to = Q(state='valid') | Q(state='modify'))
idUser = models.ForeignKey(User,db_column = 'idUser',verbose_name = 'Utilisateur',limit_choices_to = Q(state='valid') | Q(state='modify'))
and in admin.py :
class SecondaryGroupAdmin(admin.ModelAdmin):
form = SecondaryGroupAdminForm
list_display = ('idUser','idGroup')
raw_id_fields = ('idUser','idGroup',)
and I obtain this error in Admin edit form :
Caught an exception while rendering: 'Q' object has no attribute 'items'
Thanks in advance.
Bye.
Change History (10)
comment:1 by , 16 years ago
| Resolution: | → invalid |
|---|---|
| Status: | new → closed |
follow-up: 3 comment:2 by , 16 years ago
| Resolution: | invalid |
|---|---|
| Status: | closed → reopened |
Unless I'm missing something, this is a bug in Django, not a user error. A perfectly valid limit_choices_to specified as a Q object, that works fine with the seclect box interface, causes an exception if the field is included in raw_id_fields:
Environment:
Request Method: GET
Request URL: http://localhost:8000/admin/crossword/puzzles/14310/
Django Version: 1.2 pre-alpha SVN-11616
Python Version: 2.5.2
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.admin',
'django.contrib.admindocs',
'django.contrib.sites',
'django.contrib.humanize',
'xword.crossword']
Installed Middleware:
('django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.doc.XViewMiddleware')
Template error:
[snip irrelevant template context and rendering traceback]
Exception Type: TemplateSyntaxError at /admin/crossword/puzzles/14310/
Exception Value: Caught an exception while rendering: 'Q' object has no attribute 'items'
Original Traceback (most recent call last):
File "d:\u\kmt\django\trunk\django\template\debug.py", line 71, in render_node
result = node.render(context)
File "d:\u\kmt\django\trunk\django\template\debug.py", line 87, in render
output = force_unicode(self.filter_expression.resolve(context))
File "d:\u\kmt\django\trunk\django\utils\encoding.py", line 71, in force_unicode
s = unicode(s)
File "d:\u\kmt\django\trunk\django\forms\forms.py", line 356, in __unicode__
return self.as_widget()
File "d:\u\kmt\django\trunk\django\forms\forms.py", line 391, in as_widget
return widget.render(name, data, attrs=attrs)
File "d:\u\kmt\django\trunk\django\contrib\admin\widgets.py", line 113, in render
params = self.url_parameters()
File "d:\u\kmt\django\trunk\django\contrib\admin\widgets.py", line 145, in url_parameters
params = self.base_url_parameters()
File "d:\u\kmt\django\trunk\django\contrib\admin\widgets.py", line 134, in base_url_parameters
for k, v in self.rel.limit_choices_to.items():
AttributeError: 'Q' object has no attribute 'items'
The code in ForeignKeyRawIdWidget is assuming that limit_choices_to will be a dict, or at least support items(), and that's not a valid assumption since limit_choices_to may also be a Q object.
If I am missing something please point it out, I'm just not seeing the user error here.
follow-up: 4 comment:3 by , 16 years ago
Replying to kmtracey:
The code in
ForeignKeyRawIdWidgetis assuming thatlimit_choices_towill be a dict, or at least supportitems(), and that's not a valid assumption sincelimit_choices_tomay also be a Q object.
Huh - you learn something new every day. I wasn't aware that this usage of Q was documented (or even possible). In which case, yes, there is something unusual going on here.
follow-up: 7 comment:4 by , 16 years ago
Replying to russellm:
I didn't realize it either until I went to point the django-user's query to the doc on limit_choice_to, and there it was, documented. Not sure how this can be fixed, as I think the raw widget is trying to build a URL for the popup to select from the limited set of related objects. Not sure a Q object can be encoded into a URL query string for an admin filter lookup...but I'm also exhausted at the moment so I could be missing something obvious.
comment:5 by , 16 years ago
| Cc: | added |
|---|
comment:6 by , 16 years ago
| milestone: | → 1.2 |
|---|---|
| Triage Stage: | Unreviewed → Accepted |
comment:7 by , 16 years ago
Replying to kmtracey:
Not sure a Q object can be encoded into a URL query string for an admin filter lookup...but I'm also exhausted at the moment so I could be missing something obvious.
Indeed. A Q object which only uses "and" connectors could be dumped into a querystring fairly easily, but one which uses "or" can't because there's no way to represent that short of the Q object itself.
My vote would be for documenting that Q in limit_choices_to isn't compatible with raw-id lookups, and leaving it at that.
comment:8 by , 16 years ago
| Resolution: | → fixed |
|---|---|
| Status: | reopened → closed |
(In [12728]) Fixed #12024: Changed admin code to avoid raising an exception when a field listed
in raw_id_fields has limit_choices_to specified as a Q object.
Tweaked a test to trigger the condition and verify the fix.
Finally, documented that limit_choices_to specified as a Q object has no effect
on the choices available for fields listed in raw_id_fields, and removed another
incorrect note that claimed limit_choices_to had no effect on inlines in the admin.
comment:9 by , 16 years ago
(In [12729]) [1.1.X] Fixed #12024: Changed admin code to avoid raising an exception when a field listed
in raw_id_fields has limit_choices_to specified as a Q object.
Tweaked a test to trigger the condition and verify the fix.
Finally, documented that limit_choices_to specified as a Q object has no effect
on the choices available for fields listed in raw_id_fields, and removed another
incorrect note that claimed limit_choices_to had no effect on inlines in the admin.
r12728 from trunk.
Trac isn't for solving end-user questions - it's for tracking bugs in Django itself. In this case, you have misunderstood what Q is for. If you want more explanation, follow up with a message on django-users.