Opened 6 years ago

Closed 5 years ago

Last modified 4 years ago

#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: tubaman Triage Stage: Accepted
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: UI/UX:

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 Changed 6 years ago by russellm

  • Needs documentation unset
  • Needs tests unset
  • Patch needs improvement unset
  • Resolution set to invalid
  • Status changed from new to closed

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.

comment:2 follow-up: Changed 6 years ago by kmtracey

  • Resolution invalid deleted
  • Status changed from closed to 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.

comment:3 in reply to: ↑ 2 ; follow-up: Changed 6 years ago by russellm

Replying to kmtracey:

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.

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.

comment:4 in reply to: ↑ 3 ; follow-up: Changed 6 years ago by kmtracey

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 Changed 6 years ago by tubaman

  • Cc tubaman added

comment:6 Changed 6 years ago by russellm

  • milestone set to 1.2
  • Triage Stage changed from Unreviewed to Accepted

comment:7 in reply to: ↑ 4 Changed 5 years ago by ubernostrum

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 Changed 5 years ago by kmtracey

  • Resolution set to fixed
  • Status changed from reopened to 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 Changed 5 years ago by kmtracey

(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.

comment:10 Changed 4 years ago by jacob

  • milestone 1.2 deleted

Milestone 1.2 deleted

Note: See TracTickets for help on using tickets.
Back to Top