DRF框架的過濾器功能

        今天第一個用drf框架寫了個簡陋的後臺, 算是首次嘗試前後臺分離開發, 接口調試基本完成。 通過這個應用的編寫, 慢慢的也認識到了DRF框架的強大, 比如今天又學會了關於過濾的新姿勢!

        話說之前寫過濾一致是這樣子的, 比如

def get_object(self):
    return Book.objects.filter(author__pk=1)

是不是長得很平平無奇?剛開始學的時候一直是這麼寫的, 甚至之前瞭解不夠的情況下,只會這麼寫:

def get_object(self):
    return Book.objects.filter(name='三國演義')

這樣的話, 當前端想要查詢的時候還要後臺去解析參數, 有時候針對不同的類需要過濾的話, 那每個地方都得寫這麼一段

def retrieve(request, *args, **kwargs)
    name = self.request.query_params.get('name', None)
    if name:
        book = Book.objects.filter(name=name).first()
        serializer = BookSerializer(book, many=False)
        serializer.valid(raiseException=True)
        return Response(serializer.data)
    else:
        raise BadRequestError('error')

看起來老長老長了, 還都是些無效的代碼。直到後來看人家的代碼, 再在官網上重新看了下, 原來有個東西叫做過濾器!只要在視圖類中加入一行代碼就OK了, 前提是你得安裝Django_filter, 代碼就像下面這樣:

from rest_framework import mixins, viewsets, filters
from django_filters.rest_framework import DjangoFilterBackend

class BookViewSet(viewsets.GenericViewSet,
                     mixins.CreateModelMixin,
                     mixins.UpdateModelMixin,
                     mixins.DestroyModelMixin,
                     mixins.RetrieveModelMixin,
                     mixins.ListModelMixin):
    queryset = Book.objects.all()
    filter_backends = (DjangoFilterBackend, filters.SearchFilter)
    filter_fields = ('name', 'author__id')

然後你就可以直接通過http://baseurl/api/book?name=三國演義或者http://baseurl/api/book?author__id=1來訪問啦, 當然聰明如你肯定也想到了把後面的__id去掉, 前端需要啥自己補上__就OK了。是不是很強大?甚至你可以使用比較的方式例如age__gt=3這種, 只要你的filter_fields傳入的字段是對的, 一旦前端傳錯參數也沒啥關係, 就當沒有後面那一截就行了。可以說用起來非常的方便了。

那如果你想要有更高級的用法怎麼辦呢? 答案是你可以使用filterSet進行定製。

class GoodsFilter(django_filters.rest_framework.FilterSet):
    min_price = django_filters.NumberFilter(name='shop_price', lookup_expr='gt')

    class Meta:
        model = Goods
        fields = ['min_price']

這樣你就可以在視圖函數中使用這個過濾器

from .filters import GoodsFilter

class xxView(xxxView):
    filter_class = GoodsFilter

就這兩行代碼, 一個視圖函數就完成了, 而從前端來看,依舊是之前的效果和字段, 是不是很嗨皮呢?

與過濾器並提的其實還有排序和分組, 其形式和此類似, 就改天再說咯!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章