2011-06-22 82 views
16

我继承了一个Django v1.2.4应用程序,并且正在添加多个修复程序和改进。在这个过程中,我突然开始遇到以下错误:Django:不允许过滤%筛选器%

SuspiciousOperation at 
/hometeam/admin/players/playeryear/ 

Filtering by team__season__season_start_date__year not allowed 

当我试图选择一个输入字段(项目通过与领域相关的放大镜访问将显示在管理界面的弹出窗口此错误)。

我打开了调试程序,但我无法确定此错误发生的位置或最近的哪个更改导致它启动。你能帮我正确解析调试输出来追踪导致这个问题的错误过滤器吗?

播放器/ admin.py包含以下类:

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'] 

注释掉list_displaylist_filter声明不会改变的问题。

下面是一些调试输出。我可以根据需要发布更多信息。

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 

我已经应用了建议的修补程序https://code.djangoproject.com/changeset/15140,但补丁后没有变化。任何指导将不胜感激。

回答

25

此问题已根据Chris Adams' blog提供的说明得到解决。 Django 1.2.4引入了一项新的安全功能,该功能限制了Daniel Roseman在其answer中提到的使用“通过查询字符串进行任意跨模式查找”的功能。

此版本的解决方法是在FooAdmin定义lookup_allowed方法(“PlayerYearAdmin”在我的情况),对所有要启用这些过滤器的返回true。就我而言,lookup_allowed是这样的:

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) 

您还可以绕过安全检查完全,有效地阐明,所有查询是被允许。这是之前的1.2.4版本的默认行为:

def lookup_allowed(self, key): 
    return True 

这可能是值得一提的是版本1.2.5 added a third parameter,以lookup_allowed。如果您正在使用的版本,你可以定义lookup_allowed这样的:

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) 
+3

很棒的发现。谢谢。 – Cerin

1

作为release notes for 1.2.4状态,不再允许通过querystring进行任意跨模型查找,因为它们存在安全风险。该补丁并不意味着重新启用它们。

您需要在admin的list_filter属性中明确指定允许的关系。不幸的是,这只能从1.3版本开始,所以你需要升级。

+0

我宁愿找到错误的过滤器,而不是升级。你有关于如何实现这一目标的任何建议? –

+0

您很可能会在自定义管理模板中找到它。 –

+0

@chrisdpratt:一个好主意,但在这种情况下,我没有使用自定义管理模板。 –