今天第一個用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
就這兩行代碼, 一個視圖函數就完成了, 而從前端來看,依舊是之前的效果和字段, 是不是很嗨皮呢?
與過濾器並提的其實還有排序和分組, 其形式和此類似, 就改天再說咯!