【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
    }
]
posted @ 2023-09-14 16:16  小C学安全  阅读(747)  评论(0编辑  收藏  举报