将 list_filter 的可能过滤器限制为非空过滤器
我有一个模型:
class Foo(models.Model):
attribute = models.IntegerField()
user = models.ForeignKey(user)
和一个模型管理员:
class FooAdmin(admin.ModelAdmin):
list_filter = ('attribute',)
在管理员中,我只显示活动用户的 Foo 对象,但属性过滤器为我提供所有可能的属性,甚至是那些不为该用户返回任何对象的属性。最后,我有很多不同的过滤器值,其中大多数对用户来说毫无用处。我如何将这些过滤器值限制为与用户匹配的值。
希望这是可以理解的
干杯
解决方案: 在应用程序的 admin.py 中放置:
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.contrib.auth.models import User
from sets import Set
class CustomChoiceFilterSpec(ChoicesFilterSpec):
def __init__(self, f, request, params, model, model_admin):
super(CustomChoiceFilterSpec, self).__init__(f, request, params, model,
model_admin)
self.lookup_kwarg = '%s__attribute__exact' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.objects = list(Set([i.attribute for i in model.objects.filter(foo__user = request.user)])) # This is the magic line :) !
def choices(self, cl):
yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': ('All')}
for val in self.objects:
yield {'selected': smart_unicode(val) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: val.attribute}),
'display': val.attribute}
def title(self):
return "Attribute"
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'compact_filter', False), CustomChoiceFilterSpec))
最后一行表示这种类型的过滤器仅适用于具有“compact_filter”作为属性的对象。
所以我们放入模型 Foo (models.py) :
attribute.compact_filter = True
i have a model :
class Foo(models.Model):
attribute = models.IntegerField()
user = models.ForeignKey(user)
and a model admin :
class FooAdmin(admin.ModelAdmin):
list_filter = ('attribute',)
In the admin, i'm only displaying Foo objects of the active user but the attribute filter give me all possible attributes even the ones which don't return any objects for that user. At the end, i have a lot of different filter values, and most of them are useless for the user. How can i limit those filter values to the ones which match the user.
hope it's understandable
Cheers
Solution :
In the admin.py of your app put :
from django.contrib.admin.filterspecs import FilterSpec, ChoicesFilterSpec
from django.contrib.auth.models import User
from sets import Set
class CustomChoiceFilterSpec(ChoicesFilterSpec):
def __init__(self, f, request, params, model, model_admin):
super(CustomChoiceFilterSpec, self).__init__(f, request, params, model,
model_admin)
self.lookup_kwarg = '%s__attribute__exact' % f.name
self.lookup_val = request.GET.get(self.lookup_kwarg, None)
self.objects = list(Set([i.attribute for i in model.objects.filter(foo__user = request.user)])) # This is the magic line :) !
def choices(self, cl):
yield {'selected': self.lookup_val is None,
'query_string': cl.get_query_string({}, [self.lookup_kwarg]),
'display': ('All')}
for val in self.objects:
yield {'selected': smart_unicode(val) == self.lookup_val,
'query_string': cl.get_query_string({self.lookup_kwarg: val.attribute}),
'display': val.attribute}
def title(self):
return "Attribute"
FilterSpec.filter_specs.insert(0, (lambda f: getattr(f, 'compact_filter', False), CustomChoiceFilterSpec))
the last line says that this type of filter will apply only to objects which have 'compact_filter' as an attribute.
So we put in our model Foo (models.py) :
attribute.compact_filter = True
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不幸的是,覆盖这些 list_filters 并不容易。
正如您在这张票上看到的,在编写我们自己的列表过滤器方面取得了巨大进展: http://code.djangoproject .com/ticket/5833 但不会出现在 1.3 版本中。
我所能建议的就是开始使用这个新词汇:“FilterSpec”来查找来自不同人的代码片段,这些人能够在 SO 和 google 上使用自定义 FilterSpec。
Django 1.3 或更低版本的 Django Admin 中的自定义过滤器
http://djangosnippets.org/snippets/1051/
我会以此为契机搞乱我自己也用 FilterSpecs 来解决这个问题!
Unfortunately, overriding those list_filters is not easy.
There's massive progress on writing our own list filters as you can see on this ticket: http://code.djangoproject.com/ticket/5833 but won't make it for 1.3.
All I can suggest is to start using this new vocabulary: "FilterSpec" to find code snippets from various people who have been able to get their custom FilterSpecs working on SO and on the googles.
Custom Filter in Django Admin on Django 1.3 or below
http://djangosnippets.org/snippets/1051/
I will take this as an opportunity to mess around with FilterSpecs myself!
为管理员设置过滤器
list_display = ('attribute_1', 'attribute_2')
设置要在特定模型的管理视图表中显示的属性。
如果这些输入正确,我确信您已经尝试过重新启动本地开发服务器和/或 apache,具体取决于您是在本地还是直接在服务器上开发应用程序。对代码文件的更改只有在重新编译后才会生效,这种情况发生在文件被导入或直接调用时。如果您尚未重新启动服务器,则该文件可能尚未重新编译,因此更改可能不会发生。
我确定您已经在 models 文件中编写了模型,并在 admin.py 文件中编写了管理员的过滤器?
Sets-up the filters for the admin
list_display = ('attribute_1', 'attribute_2')
Sets-up the attributes to show in the admin view table for your particular model.
If these have been entered correctly, I'm sure you'll have already tried re-starting the local development server and/or apache, depending on if you developing the app locally or directly on the server. Changes to your code files will only take affect after re-compliling, which happens when the file gets imported or called directly. If you haven't re-booted the server, the file may not have been re-compiled and hence the changes might not have taken place.
I'm sure you've written your model in the models file, and the filters for the admin in the admin.py file?