Django: Filtering by %filter% not allowed
Asked Answered
S

2

24

I inherited a Django v1.2.4 application and am in the process of adding several fixes and improvements. During this process, I suddenly began to encounter the following error:

SuspiciousOperation at
/hometeam/admin/players/playeryear/

Filtering by team__season__season_start_date__year not allowed

This error is displayed in the admin interface popups when I try to select an item for an input field (accessed via the magnifying glass associated with the fields).

I have debugging turned on, but I am unable to determine where this error is occurring or which recent change caused it to start. Can you help me to properly parse the debugging output to track down the errant filter that is causing this problem?

players/admin.py contains the following class:

class PlayerYearAdmin(FkAutocompleteAdmin):
    related_search_fields = {
        'team': ('school__school',),
        'player': ('first_name', 'last_name'),
    }
    list_display = ['player', 'team', 'player_year_in_school']
    list_filter = ['team']
    search_fields = ['player__first_name', 'player__last_name']
    ordering = ['player__last_name', 'player__first_name']

Commenting out the list_display and list_filter statements does not change the problem.

Below is some of the debugging output. I can post more as needed.

Request Method: GET

Request URL:    http://204.232.208.57:8010/hometeam/admin/players/playeryear/?team__season__season_start_date__year=2010&team__sport__sport=Boys%20Basketball&t=id&pop=1

Django Version: 1.2.4

Exception Type: SuspiciousOperation

Exception Value:    Filtering by team__season__season_start_date__year not allowed

Exception Location: /usr/local/lib/python2.6/dist-packages/Django-1.2.4-py2.6.egg/django/contrib/admin/views/main.py in get_query_set, line 193

Python Executable:  /usr/bin/python

I have already applied the patch suggested at https://code.djangoproject.com/changeset/15140, but there was no change after the patch. Any guidance will be appreciated.

Steamer answered 22/6, 2011 at 13:57 Comment(0)
S
45

This issue has been solved according to the instructions provided at Chris Adams' blog. Django 1.2.4 introduced a new security feature that limited the ability to use "arbitrary cross-model lookups via querystring" as noted by Daniel Roseman in his answer.

The workaround for this version is to define a lookup_allowed method in FooAdmin ('PlayerYearAdmin' in my case) that returns true for all of the filters you wish to enable. In my case, lookup_allowed looked like this:

def lookup_allowed(self, key):
    if key in ('team__season__season_start_date__year', 'team__sport'):
        return True
    return super(PlayerYearAdmin, self).lookup_allowed(key)

You can also bypass the security check altogether, effectively stating that all lookups are allowed. This was the default behavior prior to version 1.2.4:

def lookup_allowed(self, key):
    return True

It may be worth noting that version 1.2.5 added a third parameter, value, to lookup_allowed. If you are using that version, you can define lookup_allowed like this:

def lookup_allowed(self, key, value):
    if key in ('team__season__season_start_date__year', 'team__sport'):
        return True
    return super(PlayerYearAdmin, self).lookup_allowed(key, value)
Steamer answered 24/6, 2011 at 13:7 Comment(0)
H
5

As the release notes for 1.2.4 state, arbitrary cross-model lookups via querystring are no longer allowed, as they are a security risk. That patch is not meant to re-enable them.

You need to specify the allowed relations explicitly in the admin's list_filter property. Unfortunately, this was only possible from version 1.3, so you'll need to upgrade.

Holdup answered 22/6, 2011 at 14:6 Comment(6)
I would prefer finding the errant filter instead of upgrading. Do you have any suggestions regarding how to achieve that?Steamer
You would most likely find that in a custom admin template.Midkiff
@chrisdpratt: A good idea, but in this case I am using no custom admin templates.Steamer
Well, how to do you get to that URL? The problem is in the querystring of the URL mentioned in the traceback, as @Daniel pointed out. The "fix" is to remove the offending bit from the querystring.Midkiff
@chrisdpratt: I access that popup via a clickable link next to the input field. After a little investigation, I determined that the link is generated by an inline autocomplete module we are using. I will investigate that module to see how the URL is assembled.Steamer
@Daniel Roseman: Thank you for your good help. I was able to stumble upon an answer that worked well for my situation, and did not require an upgrade. Please see the posted answer for details.Steamer

© 2022 - 2024 — McMap. All rights reserved.