django框架最大的优势就是帮我们内置了一个开箱即用的管理后端,虽然样式上略显粗糙,不太符合国人的审美,但不得不说功能还是非常强大,并且还不断跟随django本身进行更新升级,如果要选后端的管理模板的话,我自己还是比较喜欢原生这个管理后端,把不符合需求的页面重写,也非常方便,并且它内置的一些功能也能很好的利用,比起参差不齐的第三方管理后端,我个人认为要好很多!
在实际项目中,往往有些需求就是让客户弄得非常复杂,其实用户都不一定理解他这么做的目的,但作为开发者,我们对需求往往是没有发言权的,更多时候是考虑如何实现客户的需求!
那么,自定义过滤筛选功能这块我相信很多人都会遇到,今天就带大家了解下,如何自定义django管理后端的过滤器!
在django后端注册一个模型,我们一般会继承ModelAdmin这个类,这个类有一个list_filter的属性,设置list_filter便可以激活管理更改列表页面右侧的侧栏过滤器,如下图所示:
list_filter
应是一个元素的列表或元组,其中每个元素应是下列类型之一:
一个字段名,其中指定的字段应该是 BooleanField``、CharField
、DateField
、DateTimeField
、IntegerField
、ForeignKey
或 ManyToManyField
,例如:
class PersonAdmin(admin.ModelAdmin):
list_filter = ('is_staff', 'company')
list_filter
中的字段名也可以使用 __
查找来跨越关系,例如:
class PersonAdmin(admin.UserAdmin):
list_filter = ('company__name',)
虽然,很多时候这个已经能很好的满足我们基本的需求,但难免有一些比较烧脑的需求,就需要我们去定制这个过滤器,那么我们该如何做呢?
只需要继承 django.contrib.admin.SimpleListFilter
的类,还需要为期提供 title
和 parameter_name
属性,并覆盖 lookups
和 queryset
方法,例如:
from datetime import date
from django.contrib import admin
from django.utils.translation import gettext_lazy as _
class DecadeBornListFilter(admin.SimpleListFilter):
# 自定义过滤器
# title顾名思义就是定义这个过滤器的名称
title = _('decade born')
# parameter_name指的是get请求的参数名,也就是url/?decade=''
parameter_name = 'decade'
def lookups(self, request, model_admin):
"""
重写该lookups方法来定义过滤器需要显示的内容
这个应该返回的是一个二元元组,或者二元列表元组都可以
其中每项元组的第一个值为url中decade参数的值,第二个值为人类可读的显示在过滤器列表的项
一般我们进行筛选的时候利用queryset方法的values_list方法筛选的格式正好符合要求!
可以直接作为返回值,无需二次构造数据结构!
"""
return (
('80s', _('in the eighties')),
('90s', _('in the nineties')),
)
def queryset(self, request, queryset):
"""
重写这个queryset方法就可以根据url中传的参数去筛选列表的值
两个参数分别为request和queryset,其中request参数与普通视图的request参数是一致的
queryset代表的是该模型的列表,要根据当前列表筛选,只需要在queryset数据层再加一层filter筛选即可
"""
# 注意:这里的self.value()获取的就是当前url中参数的值,其他的就按正常的视图筛选过滤操作即可
if self.value() == '80s':
return queryset.filter(birthday__gte=date(1980, 1, 1),
birthday__lte=date(1989, 12, 31))
if self.value() == '90s':
return queryset.filter(birthday__gte=date(1990, 1, 1),
birthday__lte=date(1999, 12, 31))
# 使用以上过滤器只需要将我们定义好的引入到list_filter中即可
class PersonAdmin(admin.ModelAdmin):
list_filter = (DecadeBornListFilter,)
当然你还可以很轻松的自定义他的模板显示样式:
class FilterWithCustomTemplate(admin.SimpleListFilter):
template = "custom_template.html"
具体的例子请看 Django 提供的默认模板(admin/filter.html
)。