在我的项目中,我使用DRF作为后端,将Angular作为前端。
的Django == 1.10 djangorestframework == 3.7.1
我需要DRF的所有回复采用以下格式。
{
"status": "", // 200,400,.....etc
"error": "", // True, False
"data": [], // data
"message": "" // Success messages
}
目前正在
[
{
"id": 1,
"name": ""
},
{
"id": 2,
"name": ""
}
]
应该是
{
"status": "200",
"error": "False",
"data": [
{
"id": 1,
"name": ""
},
{
"id": 2,
"name": ""
}
],
"message": "Success"
}
为此我编写了一个自定义视图集并覆盖了函数列表,详细信息,创建,更新
class ResponseModelViewSet(viewsets.ModelViewSet):
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
custom_data = {
"status": True,
"error": False,
"message": 'message',
"data": serializer.data
}
return Response(custom_data)
def create(self, request, *args, **kwargs):
serializer = self.get_serializer(data=request.data)
serializer.is_valid(raise_exception=True)
self.perform_create(serializer)
headers = self.get_success_headers(serializer.data)
custom_data = {
"status": True,
"error": False,
"message": 'message',
"data": serializer.data
}
return Response(custom_data, status=status.HTTP_201_CREATED, headers=headers)
def retrieve(self, request, *args, **kwargs):
instance = self.get_object()
serializer = self.get_serializer(instance)
custom_data = {
"status": True,
"error": False,
"message": 'message',
"data": serializer.data
}
return Response(custom_data)
def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
instance = self.get_object()
serializer = self.get_serializer(instance, data=request.data, partial=partial)
serializer.is_valid(raise_exception=True)
self.perform_update(serializer)
if getattr(instance, '_prefetched_objects_cache', None):
# If 'prefetch_related' has been applied to a queryset, we need to
# forcibly invalidate the prefetch cache on the instance.
instance._prefetched_objects_cache = {}
custom_data = {
"status": True,
"error": False,
"message": 'message',
"data": serializer.data
}
return Response(custom_data)
在视图中我使用自定义视图集
from common.baseview import ResponseModelViewSet
class PositionViewsets(ResponseModelViewSet):
serializer_class = PositionSerializer
permission_classes = (IsAuthenticated,)
model = Position
def get_queryset(self):
return Position.objects.filter(order__user=self.request.user)
我不确定这是否是正确的方法,或者还有其他有效的方法。 无论如何,这适用于我的自定义应用,但不适用于身份验证应用 我使用默认的休息应用
'rest_framework.authtoken',
'rest_auth',
使用用户名和密码登录并获得成功响应,如下所示。
{
"key": "e642efd0b78e08b57bf34fa999f49b70a7bfe21a"
}
相反,我需要这个。
{
"status": "200",
"error": "False",
"data": [
{
"token":{
"key":"e642efd0b78e08b57bf34fa999f49b70a7bfe21a"
}
}
],
"message": "Login Sucess"
}
表示错误
{
"status": "error",
"error": "True",
"data": [
{
"email": ["Enter a valid email address."]
}
],
"message": "Login Failed"
}
答案 0 :(得分:1)
经过一些研究后,我发现了一种方法。我不得不覆盖Modelviewsets的默认行为以输出不同的响应。
我最初创建了一个自定义的响应格式
class ResponseInfo(object):
def __init__(self, user=None, **args):
self.response = {
"status": args.get('status', True),
"error": args.get('error', 200),
"data": args.get('data', []),
"message": args.get('message', 'success')
然后在modelviewset的每个方法中使用此自定义格式
class ResponseModelViewSet(viewsets.ModelViewSet):
def __init__(self, **kwargs):
self.response_format = ResponseInfo().response
super(ResponseModelViewSet, self).__init__(**kwargs)
def list(self, request, *args, **kwargs):
response_data = super(ResponseModelViewSet, self).list(request, *args, **kwargs)
self.response_format["data"] = response_data.data
self.response_format["status"] = True
if not response_data.data:
self.response_format["message"] = "List empty"
return Response(self.response_format)
def create(self, request, *args, **kwargs):
response_data = super(ResponseModelViewSet, self).create(request, *args, **kwargs)
self.response_format["data"] = response_data.data
self.response_format["status"] = True
return Response(self.response_format)
def retrieve(self, request, *args, **kwargs):
response_data = super(ResponseModelViewSet, self).retrieve(request, *args, **kwargs)
self.response_format["data"] = response_data.data
self.response_format["status"] = True
if not response_data.data:
self.response_format["message"] = "Empty"
return Response(self.response_format)
def update(self, request, *args, **kwargs):
response_data = super(ResponseModelViewSet, self).update(request, *args, **kwargs)
self.response_format["data"] = response_data.data
self.response_format["status"] = True
return Response(self.response_format)
def destroy(self, request, *args, **kwargs):
response_data = super(ResponseModelViewSet, self).destroy(request, *args, **kwargs)
self.response_format["data"] = response_data.data
self.response_format["status"] = True
return Response(self.response_format)
答案 1 :(得分:0)
这将是更强大的解决方案,因为它可以与通用视图轻松使用。
此外,render()中的检查可以根据需要轻松更改(例如,在此解决方案中处理no-2XX)。
from rest_framework.renderers import JSONRenderer
class CustomRenderer(JSONRenderer):
def render(self, data, accepted_media_type=None, renderer_context=None):
status_code = renderer_context['response'].status_code
response = {
"status": "success",
"code": status_code,
"data": data,
"message": None
}
if not str(status_code).startswith('2'):
response["status"] = "error"
response["data"] = None
try:
response["message"] = data["detail"]
except KeyError:
response["data"] = data
return super(CustomRenderer, self).render(response, accepted_media_type, renderer_context)