Django 1.3 或更低版本的 Django Admin 中的自定义过滤器
如何向 django admin 添加自定义过滤器(显示在模型仪表板右侧的过滤器)?我知道很容易包含基于该模型字段的过滤器,但是像这样的“计算”字段怎么样:
class NewsItem(models.Model):
headline = models.CharField(max_length=4096, blank=False)
byline_1 = models.CharField(max_length=4096, blank=True)
dateline = models.DateTimeField(help_text=_("date/time that appears on article"))
body_copy = models.TextField(blank=False)
when_to_publish = models.DateTimeField(verbose_name="When to publish", blank=True, null=True)
# HOW CAN I HAVE "is_live" as part of the admin filter? It's a calculated state!!
def is_live(self):
if self.when_to_publish is not None:
if ( self.when_to_publish < datetime.now() ):
return """ <img alt="True" src="/media/img/admin/icon-yes.gif"/> """
else:
return """ <img alt="False" src="/media/img/admin/icon-no.gif"/> """
is_live.allow_tags = True
class NewsItemAdmin(admin.ModelAdmin):
form = NewsItemAdminForm
list_display = ('headline', 'id', 'is_live')
list_filter = ('is_live') # how can i make this work??
How can I add a custom filter to django admin (the filters that appear on the right side of a model dashboard)? I know its easy to include a filter based on a field of that model, but what about a "calculated" field like this:
class NewsItem(models.Model):
headline = models.CharField(max_length=4096, blank=False)
byline_1 = models.CharField(max_length=4096, blank=True)
dateline = models.DateTimeField(help_text=_("date/time that appears on article"))
body_copy = models.TextField(blank=False)
when_to_publish = models.DateTimeField(verbose_name="When to publish", blank=True, null=True)
# HOW CAN I HAVE "is_live" as part of the admin filter? It's a calculated state!!
def is_live(self):
if self.when_to_publish is not None:
if ( self.when_to_publish < datetime.now() ):
return """ <img alt="True" src="/media/img/admin/icon-yes.gif"/> """
else:
return """ <img alt="False" src="/media/img/admin/icon-no.gif"/> """
is_live.allow_tags = True
class NewsItemAdmin(admin.ModelAdmin):
form = NewsItemAdminForm
list_display = ('headline', 'id', 'is_live')
list_filter = ('is_live') # how can i make this work??
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
感谢 gpilotino 为我指明了实现这一目标的正确方向。
我注意到问题的代码使用日期时间来确定其 live 时间。所以我使用了 DateFieldFilterSpec 并将其子类化。
要使用,您可以将上述代码放入filters.py中,并将其导入到您想要添加过滤器的模型中
Thanks to gpilotino for giving me the push into the right direction for implementing this.
I noticed the question's code is using a datetime to figure out when its live . So I used the DateFieldFilterSpec and subclassed it.
To use you can put the above code into a filters.py, and import it in the model you want to add the filter to
你必须编写一个自定义的 FilterSpec (不在任何地方记录)。
请参阅此处的示例:
http://www.djangosnippets.org/snippets/1051/
you have to write a custom FilterSpec (not documentend anywhere).
Look here for an example:
http://www.djangosnippets.org/snippets/1051/
在当前的 django 开发版本中,支持自定义过滤器: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
In current django development version there is the support for custom filters: https://docs.djangoproject.com/en/dev/ref/contrib/admin/#django.contrib.admin.ModelAdmin.list_filter
不幸的是,你不能。目前非字段项不能用作list_filter条目。
请注意,即使您的管理类是一个字段,它也无法工作,因为单项元组需要逗号:
('is_live',)
You can't, unfortunately. Currently non-field items can not be used as list_filter entries.
Note that your admin class wouldn't have worked even if it was a field, as a single-item tuple needs a comma:
('is_live',)
只是旁注:您可以更轻松地使用 Django 管理上的默认刻度,如下所示:
Just a sidenote: You can use the deafult ticks on Django admin more easily like this:
这不是最佳方法(就 CPU 而言),但简单且可行,所以我这样做(对于我的小型数据库)。我的 Django 版本是 1.6。
在 admin.py 中:
...
这里的关键思想是通过 __call__() 函数访问 QuerySet 中的自定义字段。
Not an optimal way (CPU-wise) but simple and will work, so I do it this way (for my small database). My Django version is 1.6.
In admin.py:
...
Key idea here is to access custom fields in a QuerySet via __call__() function.
用户向某些国家免费提供商品。我想过滤这些国家/地区:
所有 - 所有国家/地区,是 - 免费邮资,否 - 收费邮资。
这个问题的主要答案对我来说不起作用(Django 1.3),我认为是因为
__init__
方法中没有提供field_path
参数。它还继承了DateFieldFilterSpec
。postage
字段是一个 FloatField在 self.links 中我们提供了字典。用于为每个可能的过滤器构造 HTTP 查询字符串,例如
?postage__exact=0
。过滤器我认为是累积的,因此如果之前有“否”的请求,现在我们有“是”的请求,我们必须删除“否”询问。 self.removes 指定每个查询需要删除的内容。
choices
方法构造查询字符串,说明已选择哪个过滤器并设置过滤器的显示名称。The user supplies goods to some countries postage free. I wanted to filter those countries:
All - all countries, Yes - postage free, No - charged postage.
The main answer for this question did not work for me (Django 1.3) I think because there was no
field_path
parameter provided in the__init__
method. Also it subclassedDateFieldFilterSpec
. Thepostage
field is a FloatFieldIn self.links we supply dicts. used to construct HTTP query strings like
?postage__exact=0
for each of the possible filters. Filters I think are cumulative so if there was a previous request for 'No' and now we have a request for 'Yes' we have to remove the'No' query.
self.removes
specifies what needs to be removed for each query. Thechoices
method constructs the query strings, says which filter has been selected and sets the displayed name of the filter.这是答案并尽可能简单地实现了自定义过滤器,这可能会有所帮助
Django admin日期范围过滤器
Here is the answer and implemented the custom filter as simple as possible this might help
Django admin date range filter