[英]Custom filter in Django admin for calculated fields
# models.py
class Author(models.Model):
name = models.CharField(max_length=50)
class Book(models.Model):
title = models.CharField(max_length=50)
created_time = models.DateTimeField(auto_now=False, auto_now_add=True)
writer = models.ForeignKey(Author, on_delete=models.CASCADE, related_name='books')
# admin.py
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
def get_queryset(self, request):
qs = super(AuthorAdmin, self).get_queryset(request)
return qs.annotate(books_count=Count('books'))
def books_count(self, inst):
return inst.books_count
list_display = ['author', 'books_count']
Now I have two columns in admin: Author and Books count .现在我在 admin 中有两列: Author和Books count 。
I need to add DateFieldListFilter
, but for a calculated field (not for model field).我需要添加DateFieldListFilter
,但对于计算字段(而不是模型字段)。
For example, to have a possibility show created books count by each author for last_week , last_month , last_year , etc.例如,要显示每个作者为last_week 、 last_month 、 last_year等创建的书籍计数的可能性。
Old question, and you've likely found the answer already, but I literally just did this today (mostly) - I don't think you'd be able to get a count with a filter, as that's not really what a filter does in Django admin;老问题,您可能已经找到了答案,但我今天(主要是)确实做到了这一点-我认为您无法使用过滤器进行计数,因为过滤器实际上不是这样做的在 Django 管理员中; but the quantity of results that have been returned with the filter/s applied does show on the page already但是应用过滤器返回的结果数量确实显示在页面上
From what I've found, Calculated Fields can be used with list_display in your ModelAdmin - exactly as you've done with books_count根据我的发现,计算字段可以与ModelAdmin 中的list_display一起使用 - 与您对books_count所做的完全一样
But to create a custom Filter , you have to use a subclass and work with queries instead;但是要创建自定义Filter ,您必须使用子类并使用查询; which makes sense if you think about the inner workings of what's going on如果你考虑正在发生的事情的内部运作,这是有道理的
Hopefully someone finds this useful!希望有人觉得这很有用!
from django.contrib import admin
from datetime import datetime, timedelta
class DateFieldListFilter(admin.SimpleListFilter):
title = 'Book Count Filter'
parameter_name = 'books_count'
def lookups(self, request, model_admin):
return (
('last_week', 'Last Week'),
('last_month', 'Last Month'),
('last_year', 'Last Year'),
)
def queryset(self, request, queryset):
value = self.value()
today = datetime.today().date()
if value == 'last_week':
start_date = today - timedelta(days=7)
return queryset.filter(created__gte=start_date)
elif value == 'last_month':
start_of_month = today.replace(day=1)
end_of_last_month = start_of_month - timedelta(days=1)
start_date = end_of_last_month.replace(day=today.day)
return queryset.filter(created__gte=start_date)
elif value == 'last_year':
start_date = today.replace(year=today.year - 1)
return queryset.filter(created__gte=start_date)
return queryset
@admin.register(Author)
class AuthorAdmin(admin.ModelAdmin):
list_display = ['author', 'books_count']
list_filter = (DateFieldListFilter,)
def get_queryset(self, request):
qs = super(AuthorAdmin, self).get_queryset(request)
return qs.annotate(books_count=Count('books'))
def books_count(self, inst):
return inst.books_count
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.