在Django Admin中保留过滤器

时间:2008-10-07 07:33:59

标签: python django django-admin

我想要达成的目标是:

  • 我转到管理站点,将一些过滤器应用于对象列表
  • 点击并对象进行编辑,编辑,编辑,点击“保存”
  • 网站将我带到对象列表中......未经过滤。我想记住并应用第1步中的过滤器。

有一种简单的方法吗?

7 个答案:

答案 0 :(得分:3)

不幸的是,没有简单的方法可以做到这一点。过滤似乎没有保存在任何会话变量中。

单击两次返回是常规方法,但是如果您刚刚更改了一个对象,那么它可能会非常烦人且烦人,因此不应再使用您的过滤器显示它。

如果它只是一次性的,请单击两次或再次进行过滤,这是最简单的方法。

如果您要更频繁地过滤,或者您只是想了解黑客管理员(这非常开放和简单),那么您需要写一个FilterSpec

请查看herehere,了解自己写作的人。

执行此操作的一种非常非常糟糕的方法是编辑管理界面,以便在您单击“保存”后,您将被重定向到已过滤的URL。我根本不会推荐这个,但这是一个选择。

另一种相当简单的方法是编写一个通用视图来显示过滤后的对象,然后使用Django表单从那里编辑项目。我看看这个,你会惊讶于你需要写一些代码来获得一个简单的视图/编辑页面。

答案 1 :(得分:2)

单击2次“返回”?

答案 2 :(得分:1)

有一个简单的黑客可以做到这一点,但它不是一般的解决方案,需要修改你想支持它的每个ModelAdmin。也许有一般的方法可以做到这一点,但我没有花时间在一般水平上解决它。

第一步是为过滤器编写自定义FilterSpec(请参阅Harley的帖子以获取有用的链接),这会将所选过滤器值保存在会话中(并在不再需要时将其删除)。

# in cust_admin/filterspecs.py
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec

class MyFilterSpec(ChoicesFilterSpec):

    def __init__(self, f, request, params, model, model_admin):
        super(MyFilterSpec, self).__init__(f, request, params, model,
                                           model_admin)
        if self.lookup_val is not None:
            request.session[self.lookup_kwarg] = self.lookup_val
        elif self.lookup_kwarg in request.session:
            del(request.session[self.lookup_kwarg])

# Register the filter with a test function which will apply it to any field
# with a my_filter attribute equal to True
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'my_filter', False),
                               MyFilterSpec))

您必须导入位于某处的模块,例如urls.py

# in urls.py
from cust_admin import filterspecs

在要应用过滤器的字段上设置属性:

# in models.py
class MyModel(models.Model):
    my_field = Models.IntegerField(choices=MY_CHOICES)
    my_field.my_filter = True

在自定义ModelAdmin课程中,覆盖change_view方法,以便在用户点击保存后,将其返回到列表视图,并添加其过滤字段值到URL。

class MyModelAdmin(admin.ModelAdmin):
    def change_view(self, request, object_id, extra_context=None):
        result = super(MyModelAdmin, self).change_view(request, object_id,
                                                       extra_context)
        if '_save' in request.POST:
            if 'my_field__exact' in request.session:
                result['Location'] = '/admin/myapp/mymodel/?my_field__exact=%s' \
                                     % request.session['my_field__exact']
        return result

答案 3 :(得分:0)

另一种方法是将过滤器嵌入查询集中。

您可以使用可以过滤所需方式的管理器动态创建代理模型,然后调用admin.site.register()来创建新的模型管理员。然后所有链接都与此视图相关。

答案 4 :(得分:0)

在我看来,最好覆盖ModelAdmin changelist_viewchange_view中的方法:

像这样:

class FakturaAdmin(admin.ModelAdmin):

[...]

def changelist_view(self, request, extra_context=None):
    result = super(FakturaAdmin, self).changelist_view(request, extra_context=None)
    request.session['qdict'] = request.GET
    return result

def change_view(self, request, object_id, extra_context=None):
    result = super(FakturaAdmin, self).change_view(request, object_id, extra_context)
    try:
        result['location'] = result['location']+"?"+request.session['qdict'].urlencode()
    except:
        pass
    return result

如您所愿,在保存对象后,您将返回具有活动过滤器的对象列表。

答案 5 :(得分:0)

Django项目有一个更改请求,要求提供此功能。

所有等待登记的是一些测试和文档。你可以编写这些,并帮助整个项目,或者你可以采取建议的补丁(靠近页面底部)并试一试。

https://code.djangoproject.com/ticket/6903

答案 6 :(得分:0)

此功能已作为1.6版本的一部分添加到Django,默认情况下现已启用。它在release notes

中描述
  

ModelAdmin现在在创建后保留列表视图上的过滤器,   编辑或删除对象。可以恢复之前的   通过设置preserve_filters属性清除过滤器的行为   为假。