【Django基础】django_filters使用教程
简介
Django-Filter是一个非常好用的第三方库,很好的利用了Django ORM的特性,可以使用很少的代码就扩展原有的接口,实现多种筛选功能~
安装
pip install django-filter
使用流程
使用前配置
在Django的项目配置文件中安装并配置django_filters应用:
INSTALLED_APPS = [
...
'django_filters',
]
REST_FRAMEWORK = {
# 过滤器默认后端
'DEFAULT_FILTER_BACKENDS': (
'django_filters.rest_framework.DjangoFilterBackend',),
}
创建models
name =models.CharField(verbose_name="靶机名称",max_length=64)
founder =models.CharField(verbose_name="靶机创建人",max_length=64,null=True,blank=True)
status = models.SmallIntegerField(verbose_name="运行状态",choices=action_choices,default="2")
difficulty =models.IntegerField(verbose_name="难易分数",choices=difficulty_choices,default="1")
introduce =MDTextField(verbose_name="简介",default="暂无")
host =models.CharField(verbose_name="访问地址",max_length=80,null=True,blank=True)
port =models.CharField(verbose_name="映射端口",max_length=80,null=True,blank=True)
update_time =models.DateField(verbose_name="更新时间",auto_now=True)
创建过滤器
import django_filters
#过滤器
class ShootingrangeFilter(django_filters.FilterSet):
name = django_filters.CharFilter(field_name="name", lookup_expr='icontains',label="靶机名称")
founder = django_filters.CharFilter(field_name="founder", lookup_expr='icontains',label="靶机创建人")
#field_name被过滤名称 lookup_expr过滤类型 label 标签
class Meta:
model = Shooting_range_manage
fields = {}
view.py
def shooting_range_manage(request):
form_obj =ShootingrangeFilter(request.GET,queryset=Shooting_range_manage.objects.all())
return render(request, "shooting_range_manage.html", {"filter":form_obj})
#对象名称为filter
html模板文件
查询表单filter.form和查询结果filter.qs。
<form action="" method="get">
<div class="col-lg-12 row">
{% with form=filter.form %}
{% for field in form.visible_fields %}
<div class="col-lg-3 mb-2 row">
<div>{{ field.label_tag }}</div>
<div>{% render_field field class="form-control" %}</div>
</div>
{% endfor %}
</div>
<div class="">
<button class="btn btn-secondary mb-2 " type="submit" value="submit">筛选</button>
<button type="button" class="btn btn-secondary mb-2" id="Updatebtn">更新靶场</button>
</div>
{% endwith %}
</form>
遍历查询结果
{% for form in filter.qs %}
<div class="card mb-2 col-lg-3 border-5"
style="border-radius: 0;border-color: black;background-color:#303030">
<div class="card-header text-center">
{{ form.name }}
</div>
其中render_field需要先安装django-widget-tweaks即可使用,主要用于给表单的字段添加css类名。
详解过滤器
过滤器类和Django中表单类极其类似,写法基本一样,目的是指明过滤的时候使用哪些字段进行过滤,每个字段可以使用哪些运算。运算符的写法基本参照Django的ORM中查询的写法,比如:大于等于,小于等于用"gte",“lte”等等
可以通过模型快速构建过滤器类
class BookFilter(filters.FilterSet):
class Meta:
model = Bookinfo # 模型名
fields = ['btitle','bcomment'] # 可以使用的过滤字段
Meta中出现的fields是指过滤条件中可以出现的字段,默认是精确判等,查询的时候可以这样用:
bcomment=80
http://127.0.0.1:8000/book/?btitle=&bcomment=80
如果不是判等,可以自定义过滤字段进行过滤:
过滤器中常用的字段类型,这些类型要输模型中对应字段类型兼容
CharFilter 字符串类型
BooleanFilter 布尔类型
DateTimeFilter 日期时间类型
DateFilter 日期类型
DateRangeFilter 日期范围
TimeFilter 时间类型
NumberFilter 数值类型,对应模型中IntegerField, FloatField, DecimalField
参数说明:
field_name: 过滤字段名,一般应该对应模型中字段名
lookup_expr: 查询时所要进行的操作,和ORM中运算符一致
Meta字段说明
model: 引用的模型,不是字符串
fields:指明过滤字段,可以是列表,列表中字典可以过滤,默认是判等;也可以字典,字典可以自定义操作
exclude = ['password'] 排除字段,不允许使用列表中字典进行过滤
lookup_expr参数是可选的,它默认为"exact",即使用等于号"="进行精确匹配。除了"exact"之外,还有一些其他的可用操作符,例如:
iexact:不区分大小写的等于号匹配
contains:包含匹配
icontains:不区分大小写的包含匹配
gt:大于匹配
gte:大于等于匹配
lt:小于匹配
lte:小于等于匹配
in:范围内匹配
startswith:以某个值开头的匹配
istartswith:不区分大小写的以某个值开头的匹配
endswith:以某个值结尾的匹配
iendswith:不区分大小写的以某个值结尾的匹配
自定义过滤字段:
class BookFilter(filters.FilterSet):
btitle = filters.CharFilter(field_name='title',lookup_expr='icontains')
pub_year = filters.CharFilter(field_name='bpub_date',lookup_expr='year')
pub_year__gt = filters.CharFilter(field_name='bpub_date',lookup_expr='year__gt')
bread__gt = filters.NumberFilter(field_name='bread',lookup_expr="gt")
bread__lt = filters.NumberFilter(field_name='bread',lookup_expr="lt")
class Meta:
model = Bookinfo
fields = ['title','bread','bcomment']
自定义字段名可以和模型中不一致,但一定要用参数field_name指明对应模型中的字段名
日期查询
#定义按年查询,
pub_year = filters.CharFilter(field_name='bpub_date',lookup_expr='year')
# 年份应该大于某值
pub_year__gt = filters.CharFilter(field_name='bpub_date',lookup_expr='year__gt')
#年份应该小于某值
bread__lt = filters.NumberFilter(field_name='bread',lookup_expr="lt")
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=&pub_year=&pub_year__gt=2014&bread__gt=&bread__lt=
##查询结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
}
]
标题查询
# btitle查询的时候可以进行包含查询,icontains在ORM中表示不区分大小的包含
btitle = filters.CharFilter(field_name='btitle',lookup_expr='icontains')
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=%E5%B0%84%E9%9B%95&pub_year=&pub_year__gt=&bread__gt=&bread__lt=
结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
}
]
阅读数查询
# 阅读数大于
bread__gt = filters.NumberFilter(field_name='bread',lookup_expr="gt")
# 阅读数小于
bread__lt = filters.NumberFilter(field_name='bread',lookup_expr="lt")
示例:
http://127.0.0.1:8000/book/?title=&bread=&bcomment=&btitle=&pub_year=&pub_year__gt=&bread__gt=20&bread__lt=100
结果:
[
{
"id": 1,
"title": "射雕英雄传",
"bpub_date": "2020-02-18",
"bread": 30,
"bcomment": 80,
"bimage": null
},
{
"id": 6,
"title": "连城诀",
"bpub_date": "2009-10-23",
"bread": 30,
"bcomment": 90,
"bimage": null
}
]