Django(69)最好用的過濾器插件Django-filter


前言

  如果需要滿足前端各種篩選條件查詢,我們使用drf自帶的會比較麻煩,比如查詢書名中包含“國”字,日期大於“2020-1-1”等等諸如此類的請求,Django-filter這個組件就是要解決這樣的問題。
 

1.安裝

Django-filter支持的Python版本和Django版本、DRF版本如下:

  • Python: 3.5, 3.6, 3.7, 3.8
  • Django: 1.11, 2.0, 2.1, 2.2, 3.0
  • DRF: 3.10+

在虛擬環境中安裝

pip3 install django-filter

Djangosettings.py文件中安裝並配置django_filters應用:

INSTALLED_APPS = [
    ...
    'django_filters',
]

REST_FRAMEWORK = {
   # 過濾器默認后端
    'DEFAULT_FILTER_BACKENDS': (
           'django_filters.rest_framework.DjangoFilterBackend',),
}

 

2.使用流程

我們通過一個簡單的圖書查詢來說明如果在DRF中使用Django-filter過濾器。圖書模型如下:

# models.py
class BookInfo(models.Model):
    title = models.CharField(max_length=200,verbose_name='標題')
    pub_date = models.DateField(blank=True, null=True,verbose_name='出版日期')
    read = models.IntegerField(null=True,verbose_name='閱讀數量')
    comment = models.IntegerField(null=True,verbose_name='評論數量')
    image = models.CharField(max_length=200, blank=True, null=True,verbose_name='圖片')

    class Meta:
        db_table = 'bookInfo'
        verbose_name = "圖書"

序列化類:

# serializers.py
class BookSerializer(serializers.ModelSerializer):
    class Meta:
        model = BookInfo
        fields = '__all__'

自定義過濾器類:

# filters.py
from django_filters import rest_framework as filters
from . models import BookInfo
class BookFilter(filters.FilterSet):
    min_read = filters.NumberFilter(field_name="read", lookup_expr='gte')
    max_read = filters.NumberFilter(field_name="read", lookup_expr='lte')

    class Meta:
        model = BookInfo
        fields = ['read']

在視圖中

# views.py
class BookView(ListAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookSerializer
    filter_class = BookFilter

url配置中

app_name = "api"


urlpatterns = [
    path('books/', views.BookView.as_view()),
]

現在我們想篩選閱讀數為500-1000的圖書,測試結果如下

 

詳解過濾器類

  過濾器類和Django中表單類極其類似,寫法基本一樣,目的是指明過濾的時候使用哪些字段進行過濾,每個字段可以使用哪些運算。運算符的寫法基本參照DjangoORM中查詢的寫法,比如:大於等於,小於等於用"gte""lte"等等

可以通過模型快速構建過濾器類

from django_filters import rest_framework as filters
class BookFilter(filters.FilterSet):
    class Meta:
        model = BookInfo   # 模型名
        fields = ['title','comment']  # 可以使用的過濾字段

Meta中出現的fields是指過濾條件中可以出現的字段,默認是精確判斷相等,查詢的時候可以這樣用:

http://127.0.0.1:8000/api/books/?comment=20&title=

以上代表查詢的是評論條數為20條的書本

如果不是判斷相等,可以自定義過濾字段進行過濾:

  • 過濾器中常用的字段類型,這些類型要輸模型中對應字段類型兼容
CharFilter         字符串類型
BooleanFilter      布爾類型
DateTimeFilter     日期時間類型
DateFilter         日期類型
DateRangeFilter    日期范圍
TimeFilter         時間類型
NumberFilter       數值類型,對應模型中IntegerField, FloatField, DecimalField
  • 過濾字段參數說明:
field_name: 過濾字段名,一般應該對應模型中字段名
lookup_expr: 查詢時所要進行的操作,和ORM中運算符一致
  • Meta字段說明
model: 引用的模型,不是字符串
fields:指明過濾字段,可以是列表,列表中字典可以過濾,默認是判斷相等;也可以字典,字典可以自定義操作
exclude = ['password'] 排除字段,不允許使用列表中字典進行過濾

自定義過濾字段:

class BookFilter(filters.FilterSet):
    title = filters.CharFilter(field_name='title',lookup_expr='icontains')  # 標題中包含
    pub_year = filters.CharFilter(field_name='pub_date',lookup_expr='year')  # 過濾年份相等
    pub_year__gt = filters.CharFilter(field_name='pub_date',lookup_expr='year__gt')  # 過濾大於年份
    read__gt = filters.NumberFilter(field_name='read',lookup_expr="gt")  # 最大閱讀數
    read__lt = filters.NumberFilter(field_name='read',lookup_expr="lt")  # 最小閱讀數

    class Meta:
        model = BookInfo
        fields = ['title','read','comment']

自定義字段名可以和模型中不一致,但一定要用參數field_name指明對應模型中的字段名
 

日期查詢

定義按年查詢

pub_year = filters.CharFilter(field_name='pub_date',lookup_expr='year')

年份應該大於某值

pub_year__gt = filters.CharFilter(field_name='pub_date',lookup_expr='year__gt')

年份應該小於某值

read__lt = filters.NumberFilter(field_name='read',lookup_expr="lt")

查詢出版年份大於2019年的書本

http://127.0.0.1:8000/api/books/?title=&read=&comment=&pub_year=&pub_year__gt=2019&read__gt=&read__lt=

查詢結果:

[
    {
        "id": 1,
        "title": "鋼鐵是怎樣練成的",
        "pub_date": "2020-10-09",
        "read": 100,
        "comment": 3,
        "image": null
    }
]

 

標題查詢

title查詢的時候可以進行包含查詢,icontainsORM中表示不區分大小的包含

title = filters.CharFilter(field_name='btitle',lookup_expr='icontains')

查詢標題中包含三國演義的書籍

http://127.0.0.1:8000/api/books/?title=%E4%B8%89%E5%9B%BD%E6%BC%94%E4%B9%89&read=&comment=&pub_year=&pub_year__gt=&read__gt=&read__lt=

查詢結果:

[
    {
        "id": 2,
        "title": "三國演義",
        "pub_date": "2019-11-12",
        "read": 200,
        "comment": 20,
        "image": null
    }
]

 

閱讀數查詢

閱讀數大於

read__gt = filters.NumberFilter(field_name='read',lookup_expr="gt")

閱讀數小於

read__lt = filters.NumberFilter(field_name='read',lookup_expr="lt")

查詢閱讀數在100-300之間的書籍

http://127.0.0.1:8000/api/books/?title=&read=&comment=&pub_year=&pub_year__gt=&read__gt=100&read__lt=300

查詢結果:

[
    {
        "id": 2,
        "title": "三國演義",
        "pub_date": "2019-11-12",
        "read": 200,
        "comment": 20,
        "image": null
    }
]

 
官方文檔:https://django-filter.readthedocs.io/en/stable/guide/install.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM