Django Admin中的自定义过滤器返回SuspiciousOperation

时间:2013-07-01 16:42:30

标签: django django-admin django-filter

我正在尝试实现this snippet的新版本,使其与Django 1.4和1.5兼容

相当多的进化,下面的代码几乎正常工作,除了Django给我一个SuspiciousOperation错误。我知道如何破解它,但我宁愿不触及Django的核心。如果您有一些建议,欢迎:

这是我的过滤器:

class RelatedNullFilterSpec(FieldListFilter):
    def __init__(self, field, request, params, model, model_admin, field_path):
        field_root, field_name = field_path.rsplit('__', 1)
        self.lookup_title = field.verbose_name
        self.title = self.lookup_title
        self.null_lookup_kwarg = '%s__isnull' % field_root
        self.null_lookup_val = request.GET.get(self.null_lookup_kwarg, None)
        self.lookup_kwarg = '%s__exact' % (field_path)
        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
        if isinstance(field, models.fields.BooleanField):
            self.lookup_choices = (
                # (None, _('All')),
                ('1', _('Yes')),
                ('0', _('No')))
        else:
            self.lookup_choices = field.get_choices(include_blank=False)
        super(RelatedNullFilterSpec, self).__init__(field, request, params, model, model_admin, field_path)

    def expected_parameters(self):
        return [self.lookup_kwarg, self.null_lookup_kwarg]

    def choices(self, cl):
        yield {'selected': self.lookup_val is None and self.null_lookup_val is None,
               'query_string': cl.get_query_string({}, [self.lookup_kwarg,self.null_lookup_kwarg]),
               'display': _('All')}
        yield {'selected': self.lookup_val is None and self.null_lookup_val=="True",
               'query_string': cl.get_query_string({self.null_lookup_kwarg:True},[self.lookup_kwarg]),
               'display': _('Null')}
        yield {'selected': self.lookup_val is None and self.null_lookup_val=="False",
               'query_string': cl.get_query_string({self.null_lookup_kwarg:False},[self.lookup_kwarg]),
               'display': _('Not Null')}
        for pk_val, val in self.lookup_choices:
            yield {'selected': self.lookup_val == smart_unicode(pk_val),
                   'query_string': cl.get_query_string({self.lookup_kwarg: pk_val},[self.null_lookup_kwarg]),
                   'display': val}

然后在我的管理员中,我有以下内容:

list_filter = ('time_added', 'time_modified', ('model1__model2__property', RelatedNullFilterSpec),)

我总是从Django BaseModelAdmin类的lookup_allowed方法中得到此错误...

在django.db.models.options中,我可以实现一个hack来覆盖或扩展self.related_fkey_lookups,但是根据我的口味它有点过于讨厌。

编辑:请注意,以下几乎标准的过滤器也会返回相同的错误:('venue__eat_venue', BooleanFieldListFilter)

一般来说,我的目标是我想要一个过滤器,允许我根据model2相关字段(Null / Not-Null)的存在/不存在以及属性的值(如果是model2)对对象进行排序相关领域存在)。这将非常方便,我认为不太具体。

最后,是的,当我没有为model1__model2__property请求此自定义过滤器时,一切正常: - )

1 个答案:

答案 0 :(得分:2)

这似乎是Django中的一个错误,当你有过滤路径的双下划线(元组的第一个元素)...在你的情况下'model1__model2__property'

注意:现在已在Django 1.7中修复

此处有更多详情: https://code.djangoproject.com/ticket/19182

这很难看,但到目前为止,我找到的唯一解决方法是将这个已修复且已覆盖的方法粘贴到您要使用ModelAdmin的{​​{1}}中:

list_filter