I. Anomalies
When using the Django Rest framework, if an exception occurs, it is often shown as follows:
{"Detail": "Not allowed."}
But the backstage often wants the common pattern:
{
"desc": "Not allowed.",
"code": +,
"data": null
}
The official website document is very clear, we need to customize exception handling, and then configure it, such as:
1. To achieve
From rest_framework.views import Exception_handler
def custom_exception_handler (exc, context):
# Call Rest Framework ' s default exception handler the
standard error response.
Response = Exception_handler (exc, context)
# Now add the HTTP status code to the response.
If response is not None:
response.data[' code ' = response.status_code
response.data[' desc '] = response.data[' Detail ']
#response. data[' data ' = None #可以存在
del response.data[' detail '] #删除detail字段 return
response
2. Configure
Configuration in settings.py
Rest_framework = {
...
...
' Exception_handler ': (
' DataAPI.common.api_exception.custom_exception_handler '
)
# ' Exception_ HANDLER ': ' My_project.my_app.utils.custom_exception_handler '
}
two. return value
As the exception shows, we often return the same type of value, as shown below, basic data format and paging format (later)
{
"desc": "Page Success", #描述信息
"code": #响应码 to start with 2 is the success of
"data": {
"detail": array[2], #当前页数据列表
" Total ": 6, #页面总数
" page ": 2 #当前页面
}
}
When we use serialization in the Django Rest Framework, we return the data directly and do not conform to the data we want, so we return the data via a custom response: for example, use Apiview
From django.utils import six to Rest_framework.response import response from rest_framework.serializers import Serializ Er class Jsonresponse (Response): "" "" "" an httpresponse that allows it data to is rendered into arbitrary medi
A types. "" "Def __init__ (self, data=none, Code=none, Desc=none, Status=none, template_name= None, Headers=none, Exception=false, Content_type=none): "" "alters the init arguments SL
ightly.
For example, drop ' template_name ', and instead with ' data '. Setting ' renderer ' and ' media_type ' would typically be deferred, for example being set automatically by the ' Apivie
W '. "" Super (Response, self). __init__ (None, Status=status) if isinstance (data, serializer): Msg = (' You passed a serializer instance as data, but ' probably meant to pass serialized '. Data ' or '. Error '. REpresentation. ' ) Raise Assertionerror (msg) self.data = {"Code": Code, "desc": desc, "Data": Data} Self.templ
Ate_name = Template_name Self.exception = Exception Self.content_type = Content_Type If headers:
For name, value in Six.iteritems (headers): self[name] = value
Example:
def get (self, request, HOUSE_PK): House
= get_object_or_404 (house, PK=HOUSE_PK) #获取数据
data = Houseserializer ( House) #序列化 return
api_response. Jsonresponse (Data=data.data, Code=status. HTTP_200_OK, desc= ' Get House Success ') #使用上面的进行返回
Results:
Success: Successful use of Jsonresponse return
{"
desc": "Get House Success",
"code": "
Data": {
"PK": 7,
"name": "VVVVVVV",
"staff": { c10/> "Phone": "Xxxxxxxxxx",
"username": "Yuan"}}
Fail: Failure uses the above exception for processing: Custom_exception_handler
{
"code": 404,
"desc": "Not found. "
}
three. Paging Implementation
As shown in the result return value, many uses need to implement paging functionality, but the Django Rest Framework has its own paging capabilities that can only be mixins. Listmodelmixin and generics. Genericapiview classes inherits these two classes, and we usually inherit apiview for flexibility, so we need to use the paging feature ourselves.
Data Base format:
{
"desc": "Page Success", #描述信息
"code": #响应码 to start with 2 is the success of
"data": {
"detail": array[2], #当前页数据列表
" Total ": 6, #页面总数
" page ": 2 #当前页面
}
}
Here I am using the API interface, such as my (self can add other validation, such as Page_size max):
From Django.core.paginator import Paginator, Pagenotaninteger, emptypage from rest_framework import status from Dataapi.c
Ommon Import api_response #第二条中的返回值格式 jsonresponse def api_paging (OBJS, request, serializer): "" "OBJS: Entity objects Request: Object Serializer: Serialization of the corresponding entity object "" "Try:page_size = Int (request. Get.get (' Page_size ', 2)) page = Int (request. Get.get (' page ', 1)) except (TypeError, ValueError): Return api_response. Jsonresponse (Code=status.
Http_400_bad_request, desc= ' page and page_size must be integer! ') Paginator = Paginator (Objs, page_size) # Paginator Object total = paginator.num_pages #总页数 Try:objs = Paginato R.page (page) except PAGENOTANINTEGER:OBJS = Paginator.page (1) except EMPTYPAGE:OBJS = Paginator. Page (paginator.num_pages) serializer = Serializer (OBJS, many=true) #序列化操作 return api_response.
Jsonresponse (data={' detail ': serializer.data, ' page ': page, "Total": total}, Code=status. HTTP_200_OK, desc= ' page success ') #返回
Example:
def get (self, request, Format=none): "" "
page_size:? page=1&page_size=10
page:" "
farms = Self.get_object_list () #获取数据
return api_paginator.api_paging (farms, request, Farmserializer) #分页处理, and returns
Results:
{"
desc": "Page Success", "
Code": "
Data": {
"detail": [
{
"name": "V3",
},
{
"name": "V2",
}
],
"Total": 6, #总页数
"page": 2 #当前页
}
}
Finish