DRF過濾、排序、異常處理、自定義Response、分頁
目錄
過濾
# pip安裝
# settings.py注冊
# 全局配置
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.backends.DjangoFilterBackend'],
}
class NewNewBooksView(ListAPIView):
filter_fields = ('name',)
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
re_path('books/v5/', views.NewNewNewBooksView.as_view()),
# 在路由配置中無需正則分組即可從類似http://127.0.0.1:8000/books/v5/?name=《456》的URL中提取過濾條件
注意:繼承APIView或者View的視圖類是不受過濾影響的,繼承了GenericAPIView類或者其子類的視圖類才受過濾影響
局部過濾
# 一般情況下都是局部過濾,直接在視圖類中配置即可
class NewNewNewBooksView(ListAPIView, CreateAPIView):
authentication_classes = []
throttle_classes = []
filter_backends = [DjangoFilterBackend] # 配置過濾類
filter_fields = ('name',) # 配置過濾字段
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
排序
# 全局使用
class NewNewNewBooksView(ListAPIView, CreateAPIView):
authentication_classes = []
throttle_classes = []
filter_backends = [DjangoFilterBackend,OrderingFilter]
filter_fields = ('id','price')
queryset = Book.objects.all()
serializer_class = NewBookModelSerializer
http://127.0.0.1:8000/books/v5/?ordering=-id
http://127.0.0.1:8000/books/v5/?ordering=price
異常處理
def app01_exception_handler(exc, context):
response = exception_handler(exc, context)
if not response:
return Response(data={'status': 1, 'msg': str(exc)}, status=status.HTTP_400_BAD_REQUEST)
else:
return Response(data={'status': 2, 'msg': response.data.get('detail')}, status=status.HTTP_400_BAD_REQUEST)
REST_FRAMEWORK = {
'EXCEPTION_HANDLER': 'app01.views.app01_exception_handler',
}
封裝Response對象
class APIResponse(Response):
def __init__(self, code=100, msg='成功', data=None, status=None, headers=None, content_type=None,**kwargs):
dict = {'code': code, 'msg': msg}
if data:
dict = {'code': code, 'msg': msg, 'data': data}
dict.update(kwargs)
super().__init__(data=dict, status=None,headers=None,
exception=False, content_type=None)
book_ser = BookModelSerializer(instance=book,data=request.data,partial=True) # 部分修改
分頁
三種分頁方式
from rest_framework.pagination import PageNumberPagination,LimitOffsetPagination,CursorPagination
PageNumberPagination
from rest_framework.pagination import PageNumberPagination,
class BookView(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = PageNumberPagination
REST_FRAMEWORK = {
'PAGE_SIZE': 2,
}
# page_size 即'PAGE_SIZE'
# page_query_param 即URL中的頁碼key
# page_size_query_param 指定為'size'即可在URL中傳入size參數控制索取條數
# max_page_size 硬性規定每頁最大條數
# 可以通過如下繼承改變參數值
LimitOffsetPagination
from rest_framework.pagination import LimitOffsetPagination
class MYLimitOffsetPagination(LimitOffsetPagination):
default_limit = settings.REST_FRAMEWORK['PAGE_SIZE'] # 每頁數據條數
limit_query_param = 'limit' # 指定每頁條數的key
offset_query_param = 'offset' # 相對起始位置偏移量,offset=2則從第三條開始取
max_limit = None # 每頁最大條數
class BookView(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MYLimitOffsetPagination
CursorPagination
from rest_framework.pagination import CursorPagination
class MYLimitOffsetPagination(CursorPagination):
cursor_query_param = 'cursor' # 過濾key
page_size = 3 # 每頁條數
ordering = '-id' # 排序字段
class BookView(ListAPIView):
queryset = models.Book.objects.all()
serializer_class = BookModelSerializer
pagination_class = MYLimitOffsetPagination
# 只有向前向后兩個按鈕,無法跳躍到某一頁或者某一條數據,但是相比上面兩種效率更高
使用APIView創建視圖類時分頁
class BooksAPIView(APIView):
def get(self, request, *args, **kwargs):
book_list = models.Book.objects.filter(is_delete=False)
page_cursor = PageNumberPagination()
book_list = page_cursor.paginate_queryset(book_list,request,view=self)
book_list_ser = BookModelSerializer(book_list, many=True)
return Response(data=book_list_ser.data)
浙公網安備 33010602011771號