2008-10-07 66 views
5

我想什么才达到的是:饲养过滤器

  • 我去管理网站,应用一些过滤器的对象列表
  • 我点击和对象编辑,编辑,编辑,打'保存'
  • 网站将我带到未过滤的对象列表。我想从步骤1开始记忆和应用过滤器。

有没有简单的方法来做到这一点?

回答

3

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

点击返回两次是正常的方法,但如果您刚刚更改了某个对象,以便不再使用您的过滤器显示该对象,则该方法可能会不受欢迎和烦人。

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

如果您要更频繁地进行过滤,或者您只想了解黑客入侵(这非常开放和容易),您需要编写FilterSpec

看看herehere为自己写的人的例子。

要做到这一点,真的很可怕的方法是编辑管理界面,以便在点击“保存”后,您被重定向到您过滤的URL。我不会推荐这个,但它是一个选项。

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

+1

写一个`FilterSpec`是不够的。它实际上是控制查询集的视图,它从`request.GET`中获取参数。所有`FilterSpec`真的会影响过滤器选项的显示。 – 2010-04-15 10:58:37

+0

此外,重定向到一个过滤的URL不是“真的,真的很糟糕”。过滤器选项应该在URL中明确。如果在URL中没有明显的变化,将会有一个不可见的会话变量影响查询集。 – 2010-04-15 13:52:00

1

点击2次“返回”?

+0

KISS最好:) – 2010-10-03 16:43:13

1

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

第一步是为过滤器编写自定义FilterSpec(请参阅哈利的链接帮助文章),该过滤器会将所选过滤器值保存在会话中(并在不再需要时将其删除)。

# 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 
0

另一种方法是将过滤器嵌入到queryset中。

您可以动态创建一个代理模型,其中包含一个管理器,用于过滤您想要的方式,然后调用admin.site.register()创建一个新的模型admin。所有的链接将与这个观点相关。

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 

如你所愿,后保存对象,你回去与有源滤波器对象列表。

0

在Django项目中有一个更改请求,要求准确地使用这个功能。

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

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

0

这个功能已经被添加到的Django的1.6版本的一部分,现在默认启用。它在release notes描述:现在

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