我想要达到的是:
- 我去管理站点,对对象列表应用一些过滤器
- 我点击对象编辑,编辑,编辑,点击“保存”
- 站点将我带到对象列表...未过滤。我希望记住并应用第 1 步中的过滤器。
有没有简单的方法来做到这一点?
我想要达到的是:
有没有简单的方法来做到这一点?
不幸的是,没有简单的方法可以做到这一点。过滤似乎没有保存在任何会话变量中。
单击两次返回是正常的方法,但如果您刚刚更改了一个对象以使其不再使用您的过滤器显示,那么它可能会很笨拙和烦人。
如果只是一次性的,点击返回两次或再次过滤,这是最简单的方法。
如果您要更频繁地进行过滤,或者您只是想了解如何破解管理员(这非常开放且容易),您将需要编写一个FilterSpec。
一个非常非常糟糕的方法是编辑管理界面,以便在您单击“保存”后,您将被重定向到您过滤的 URL。我根本不会推荐这个,但这是一个选择。
另一种相当简单的方法是编写一个通用视图来显示您过滤的对象,然后使用 Django 表单从那里编辑项目。我会看看这个,你会惊讶于你必须编写多少代码来获得一个简单的查看/编辑页面。
单击 2 次“返回”?
有一个简单的技巧可以做到这一点,但这不是一个通用的解决方案,需要修改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
方法,以便在用户单击save后,他们将返回到列表视图,并将其过滤字段值添加到 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
另一种方法是将过滤器嵌入到查询集中。
您可以使用按您想要的方式过滤的管理器动态创建代理模型,然后调用 admin.site.register() 来创建新的模型管理员。然后所有链接都将与此视图相关。
在我看来,最好覆盖 ModelAdmin 的方法changelist_view
和change_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
如您所愿,保存对象后,您将返回到具有活动过滤器的对象列表。
Django 项目中有一个更改请求,要求正是这个功能。
等待签入的只是一些测试和文档。您可以编写这些内容并帮助整个项目,或者您可以直接获取建议的补丁(靠近页面底部)并尝试一下。
此功能已作为 1.6 版本的一部分添加到 Django,现在默认启用。发行说明中对此进行了描述:
ModelAdmin 现在在创建、编辑或删除对象后保留列表视图中的过滤器。可以通过将 preserve_filters 属性设置为 False 来恢复之前清除过滤器的行为。