1. 程式人生 > 實用技巧 >drf 其他小元件

drf 其他小元件



drf搜尋過濾元件:
from rest_framework.generics import ListAPIView # 第一步:drf的SearchFilter - 搜尋過濾 from rest_framework.filters import SearchFilter class CarListAPIView(ListAPIView): queryset = models.Car.objects.all() serializer_class = serializers.CarModelSerializer # 第二步:區域性配置 過濾類 們(全域性配置用DEFAULT_FILTER_BACKENDS)
filter_backends = [SearchFilter] # 第三步:SearchFilter過濾類依賴的過濾條件 => 介面:/cars/?search=... search_fields = ['name', 'price'] # eg:/cars/?search=1,name和price中包含1的資料都會被查詢出 drf排序過濾元件: from rest_framework.generics import ListAPIView # 第一步:drf的OrderingFilter - 排序過濾 from rest_framework.filters import OrderingFilter
class CarListAPIView(ListAPIView): queryset = models.Car.objects.all() serializer_class = serializers.CarModelSerializer # 第二步:區域性配置 過濾類 們(全域性配置用DEFAULT_FILTER_BACKENDS) filter_backends = [OrderingFilter] # 第三步:OrderingFilter過濾類依賴的過濾條件 => 介面:/cars/?ordering=... ordering_fields = ['pk', 'price'] # eg:/cars/?ordering=-price,pk,先按price降序,如果出現price相同,再按pk升序
drf基礎分頁元件
from rest_framework.pagination import PageNumberPagination

class MyPageNumberPagination(PageNumberPagination):
    # ?page=頁碼
    page_query_param = 'page'
    # ?page=頁面 下預設一頁顯示的條數
    page_size = 3
    # ?page=頁面&page_size=條數 使用者自定義一頁顯示的條數
    page_size_query_param = 'page_size'
    # 使用者自定義一頁顯示的條數最大限制:數值超過5也只顯示5條
    max_page_size = 5
pahenations.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 如果queryset沒有過濾條件,就必須 .all(),不然分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁元件 - 給檢視類配置分頁類即可 - 分頁類需要自定義,繼承drf提供的分頁類即可
    pagination_class = pagenations.MyPageNumberPagination
views.py

drf偏移分頁元件

from rest_framework.pagination import LimitOffsetPagination
class MyLimitOffsetPagination(LimitOffsetPagination):
    # ?offset=從頭偏移的條數&limit=要顯示的條數
    limit_query_param = 'limit'
    offset_query_param = 'offset'
    # ?不傳offset和limit預設顯示前3條,只設置offset就是從偏移位往後再顯示3條
    default_limit = 3
    # ?limit可以自定義一頁顯示的最大條數
    max_limit = 5

    # 只使用limit結合ordering可以實現排行前幾或後幾
    # ?ordering=-price&limit=2  => 價格前2
pahenations.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 如果queryset沒有過濾條件,就必須 .all(),不然分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁元件 - 給檢視類配置分頁類即可 - 分頁類需要自定義,繼承drf提供的分頁類即可
    pagination_class = pagenations.MyLimitOffsetPagination
views.py

drf遊標分頁元件

# 注:必須基於排序規則下進行分頁
# 1)如果介面配置了OrderingFilter過濾器,那麼url中必須傳ordering
# 1)如果介面沒有配置OrderingFilter過濾器,一定要在分頁類中宣告ordering按某個欄位進行預設排序
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
    cursor_query_param = 'cursor'
    page_size = 3
    page_size_query_param = 'page_size'
    max_page_size = 5
    ordering = '-pk'
pahenations.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 如果queryset沒有過濾條件,就必須 .all(),不然分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 分頁元件 - 給檢視類配置分頁類即可 - 分頁類需要自定義,繼承drf提供的分頁類即可
    pagination_class = pagenations.MyCursorPagination
views.py
自定義過濾器
# 自定義過濾器,介面:?limit=顯示的條數
class LimitFilter:
    def filter_queryset(self, request, queryset, view):
        # 前臺固定用 ?limit=... 傳遞過濾引數
        limit = request.query_params.get('limit')
        if limit:
            limit = int(limit)
            return queryset[:limit]
        return queryset
filters.py
from rest_framework.generics import ListAPIView

class CarListAPIView(ListAPIView):
    # 如果queryset沒有過濾條件,就必須 .all(),不然分頁會出問題
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 區域性配置 過濾類 們(全域性配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [LimitFilter]
views.py
過濾器外掛:django-filter

安裝: pip3 install django-filter
# django-filter外掛過濾器類
from django_filters.rest_framework.filterset import FilterSet
from . import models

# 自定義過濾欄位
from django_filters import filters
class CarFilterSet(FilterSet):
    min_price = filters.NumberFilter(field_name='price', lookup_expr='gte')
    max_price = filters.NumberFilter(field_name='price', lookup_expr='lte')
    class Meta:
        model = models.Car
        fields = ['brand', 'min_price', 'max_price']
        # brand是model中存在的欄位,一般都是可以用於分組的欄位
        # min_price、max_price是自定義欄位,需要自己自定義過濾條件
自定義api/filters.py
# django-filter外掛過濾器
from django_filters.rest_framework import DjangoFilterBackend
from .filters import CarFilterSet

class CarListAPIView(ListAPIView):
    queryset = models.Car.objects.all()
    serializer_class = serializers.CarModelSerializer
    
    # 區域性配置 過濾類 們(全域性配置用DEFAULT_FILTER_BACKENDS)
    filter_backends = [DjangoFilterBackend]
    
    # django-filter過濾器外掛使用
    filter_class = CarFilterSet
    # 介面:?brand=...&min_price=...&max_price=...
    # eg:?brand=寶馬&min_price=5&max_price=10 => 5~10間的寶馬牌汽車
    
    
views.py

admin使用自定義User表:新增使用者密碼密文

from django.contrib import admin
from . import models

# 自定義User表,admin後臺管理,採用密文密碼
from django.contrib.auth.admin import UserAdmin

class MyUserAdmin(UserAdmin):
    add_fieldsets = (
        (None, {
            'classes': ('wide',),
            'fields': ('username', 'password1', 'password2', 'mobile', 'email'),
        }),
    )

admin.site.register(models.User, MyUserAdmin)