drf之過濾器詳解


drf之過濾詳解

其實也沒有多詳,只是覺得這個功能可能很好用,就稍微學細一些,繼續學習之后可能會被其他更好用的知識替代吧
文章部分來自 https://zhuanlan.zhihu.com/p/110060840

類似在視圖中操作模型的filter,不過drf提供了過濾組件,只要簡單配置,加上指定可以提供過濾的字段,就可以快速實現像在url后面用有名分組接收參數的效果

使用filter,需要先安裝模塊,可以在pycharm里安裝也可以使用pip安裝

pip install django-filter

快速配置

# setting.py
# 需要先在應用里注冊,像rest_framework
INSTALLED_APPS = [
    ...
    'django_filters',  # 需要注冊應用,
]
# 全局配置
REST_FRAMEWORK = {
    ...
    'DEFAULT_FILTER_BACKENDS':('django_filters.rest_framework.DjangoFilterBackend',)
}

在視圖中添加filter_fields屬性,指定可以過濾的字段

class StudentListView(ListAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentSerializer
    filter_fields = ('age', 'sex')

# 127.0.0.1:8000/four/students/?sex=1

高級配置

可以寫自己的過濾器類,在視圖中導入,可以實現模糊過濾,比如包含,大於,小於等等

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

模型層以圖書表為例

# 單獨寫一個過濾器文件,首先導入模塊
from django_filters.rest_framework import FilterSet
class BookFilter(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'] 排除字段,不允許使用列表中字典進行過濾

自定義過濾字段:

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
    }
]


免責聲明!

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



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