[英]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']
现在我在 admin 中有两列: Author和Books count 。
我需要添加DateFieldListFilter
,但对于计算字段(而不是模型字段)。
例如,要显示每个作者为last_week 、 last_month 、 last_year等创建的书籍计数的可能性。
老问题,您可能已经找到了答案,但我今天(主要是)确实做到了这一点-我认为您无法使用过滤器进行计数,因为过滤器实际上不是这样做的在 Django 管理员中; 但是应用过滤器返回的结果数量确实显示在页面上
根据我的发现,计算字段可以与ModelAdmin 中的list_display一起使用 - 与您对books_count所做的完全一样
但是要创建自定义Filter ,您必须使用子类并使用查询; 如果你考虑正在发生的事情的内部运作,这是有道理的
希望有人觉得这很有用!
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.