django框架的admin模塊,通過list_filter提供給用戶自定義分類查詢的接口,並且我們可以在原有類的基礎上擴展出符合自身應用場景的過濾器。
定義模型
以 Student 模型為准,管理類為 StudentAdmin。
class Student(models.Model):
id = models.AutoField(primary_key=True)
first_name = models.CharField(
max_length=20, verbose_name=u'姓')
last_name = models.CharField(
max_length=20, verbose_naem=u'名')
gender = models.IntegerField(
choices=choices_gender, verbose_name=u'性別')
age = models.IntegerField(
blank=True, verbose_name=u'年齡')
birthday = models.DateTimeField(
blank=True, verbose_name=u'生日')
@admin.register(Student) class StudentAdmin(admin.ModelAdmin): list_display = ('id', 'first_name', 'last_name', 'gender', 'age', 'birthday') list_per_page = 20
mysql創建student表:
CREATE TABLE student( id int(10) NOT NULL AUTO_INCREMENT, first_name varchar(20) NOT NULL, last_name varchar(20) NOT NULL, gender int(10) NOT NULL, age int(10) NOT NULL, birthday datetime, PRIMARY KEY (id) )ENGINE=InnoDB DEFAULT CHARSET=utf8;
直接激活過濾器
過濾器位於Admin頁面的右側,通過 list_filter 可以直接激活 Student 中已經存在的模型。注:list_filter 應該是一個列表或元組。
# 直接激活
list_filter = ('first_name',)
Filter 會自動列出所有不同的姓:

當然,其指定的字段應該是BooleanField、CharField、DateField、DateTimeField、IntegerField、ForeignKey 或ManyToManyField中的一種。並且其屬性可以為對應關聯的外鍵,通過兩個下划線指定關聯表中對應屬性:FK__key
激活帶選項的屬性
很多時候,我們的屬性只有固定的幾種類別,比如性別;一般我們會為該屬性綁定選項,這樣在展示時也更加直觀:
choices_gender = [
(0, 'male'),
(1, 'femal'),
]
這時,我們在激活該屬性的過濾器,顯示的就是選項所對應的值,而不是數據庫真正存儲的值:

自定義查詢的過濾器(SimpleListFilter)
繼承自 django.contrib.admin.SimpleListFilter
的類,需要給它提供 title
和 parameter_name
屬性來重寫 lookups
和 queryset
方法,title
為頁面上該過濾器的標題、parameter
為加載頁面時url中攜帶的參數名稱:
from django.utils.translation import ugettext_lazy as _ class AgeListFilter(admin.SimpleListFilter): title = _(u'年齡段') parameter_name = 'ages' def lookups(self, request, model_admin): return ( ('0', _(u'未成年')), ('1', _(u'成年人')), ('2', _(u'老年人')), ) def queryset(self, request, queryset): if self.value() == '0': return queryset.filter(age__lt='18') if self.value() == '1': return queryset.filter(age__gte='18', age__lte='50') if self.value() == '2': return queryset.filter(age__gt='50')
# 激活自定義過濾器
list_filter = (AgeListFilter,)
Filter 會列出 lookups
中定義的選項:

日期的區間篩選(DateRangeFilter)
默認的時間篩選只能選取某一段時間至今這樣的區間,而daterange_filter插件提供了自定義時間區間的篩選。使用DateRangeFilter
前需要安裝插件包 pip install django-daterange-filter
,並在settings.py
的 INSTALLED_APPS
中添加 daterange_filter
。
list_filter = (('birthday', DateRangeFilter), )

自定義輸入框查詢(SingleTextInputFilter)
django自帶的過濾器是不含輸入框的,但是我們可以自己重寫一個帶輸入框的過濾器,並且自己指定樣式:
from django.contrib.admin import ListFilter class SingleTextInputFilter(ListFilter): """ renders filter form with text input and submit button """ parameter_name = None template = "textinput_filter.html" def __init__(self, request, params, model, model_admin): super(SingleTextInputFilter, self).__init__( request, params, model, model_admin) if self.parameter_name is None: raise ImproperlyConfigured( "The list filter '%s' does not specify " "a 'parameter_name'." % self.__class__.__name__) if self.parameter_name in params: value = params.pop(self.parameter_name) self.used_parameters[self.parameter_name] = value def value(self): """ Returns the value (in string format) provided in the request's query string for this filter, if any. If the value wasn't provided then returns None. """ return self.used_parameters.get(self.parameter_name, None) def has_output(self): return True def expected_parameters(self): """ Returns the list of parameter names that are expected from the request's query string and that will be used by this filter. """ return [self.parameter_name] def choices(self, cl): all_choice = { 'selected': self.value() is None, 'query_string': cl.get_query_string({}, [self.parameter_name]), 'display': _('All'), } return ({ 'get_query': cl.params, 'current_value': self.value(), 'all_choice': all_choice, 'parameter_name': self.parameter_name }, ) class LastNameListFilter(SingleTextInputFilter): title = 'Last Name' parameter_name = 'last_name' def queryset(self, request, queryset): if self.value(): return queryset.filter(last_name=self.value())
將 textinput_filter.html放在templates文件夾下,並在settings.py
中TEMPLATES
的'DIRS'
,加上templates路徑。
{% load i18n %}
<h3>{% blocktrans with filter_title=title %} By {{ filter_title }} {% endblocktrans %}</h3> {#i for item, to be short in names#} {% with choices.0 as i %} <ul> <li> <form method="get"> <input type="search" name="{{ i.parameter_name }}" value="{{ i.current_value|default_if_none:"" }}"/> {#create hidden inputs to preserve values from other filters and search field#} {% for k, v in i.get_query.items %} {% if not k == i.parameter_name %} <input type="hidden" name="{{ k }}" value="{{ v }}"> {% endif %} {% endfor %} <input type="submit" value="{% trans 'apply' %}"> </form> </li> {#show "All" link to reset current filter#} <li{% if i.all_choice.selected %} class="selected"{% endif %}> <a href="{{ i.all_choice.query_string|iriencode }}"> {{ i.all_choice.display }} </a> </li> </ul> {% endwith %}

作者:Jerakrs
鏈接:https://www.jianshu.com/p/09ff09d08f75
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。