当前位置: 首页 > 面试题库 >

how overwrite Response class in django rest framework ( DRF )?

喻选
2023-03-14
问题内容

I want to overwrite Response class of django rest framework so that response
back responsive dictionary contain three parameter message, status and
data

Hello dears all

I try to change Response Class in DRF to pass two extra parameter (
message, status ) plus data provide by DRF serializer. message pass the
message like Done, User Created or etc and status pass the message like
fail or success or etc message and this message useful for reserve special
code between frontend and backend.

I want to if don’t set this parameter return empty character or null result
back to client side

for example in success mode:

{
    'data': {
        'value_one': 'some data',
        'value_two': 'some data',
        'value_three': [
                'value', 'value', 'value'
            ],
        },
    }
    'message': 'Done',
    'status': 'success',
}

and in failure mode:

{
    'data': ['any error message raise by serializer',]
    'message': 'Create User Failed',
    'status': 'failure',
}

I search about my question and found this solution:

if i inheritance DRF Response Class in my class and overwrite __init__
method and get message, data and status in this method and call init of
parent with own data structure and use this responsive class in my
functionality like this implement:

from rest_framework.response import Response


class Response(Response):

    def __init__(self, data=None, message=None, data_status=None, status=None,
                template_name=None, headers=None,
                exception=False, content_type=None):

        data_content = {
            'status': data_status,
            'data': data,
            'message': message,
        }
        super(Response, self).__init__(
            data=data_content,
            status=status,
            template_name=template_name,
            headers=headers,
            exception=exception,
            content_type=content_type
        )

in success mode call:

return Response(data=serializer.data, message='Done', data_status='success', status=200)

in failure mode call:

return Response(data=serializer.errors, message='Create User Failed', data_status='failure', status=400)

and use own Response class in all views class we had problem in this
solution: if we use GenericViews Class must be overwrite all http methods we
used in view’s logic and call own class and this is DRY!!

and other solution i found. in serialized layer, we have abstract method def to_representation(self, instance): in Serializer class and implement in
other class like ModelSerializer class inheritance Serializer and if we
overwrite this method in our serializer class and re fetch data before send to
view layer, implement like:

from collections import OrderedDict

class OurSerializer(serializer.ModelSerializer):

....

    def to_representation(self, instance):
        data = super(serializers.ModelSerializer, self).to_representation(instance)
        result = OrderedDict()
        result['data'] = data
        result['message'] = 'Done'
        result['status'] = 'sucssed'
        return result

this solution solve above problem but we have two problem again

one: if we use nested serializer and we had overwrite this function in
serializer class return bad data like:

{
    'data': {
        'value_one': 'some data',
        'value_two': 'some data',
        'value_three': {
            'data': [
                'value', 'value', 'value'
            ],
            'message': 'Done',
            'status': 'sucssed',
        },
    }
    'message': 'Done',
    'status': 'sucssed',
}

and message and status repeated and structure not pretty for client

and two: we cant handle exception in this mode and just way to handle
exception just with middleware class like this DRF Exception
Handling and this isn’t useful way, we can’t handle any type of
error occurs in view and generate comfortable separate message and status.

IF there’s another good solution to this question, please guide me.

thanks :)


问题答案:

To resolve this, best practice (that DRF has proposed) is to use ‘renderer’
classes. A renderer manipulates and returns structured response.

Django uses renderers like Template Renderer and DRF
benefits this feature and provides API Renderers.

To do so, you could provide such this renderer in a package (e.g.
app_name.renderers.ApiRenderer):

from rest_framework.renderers import BaseRenderer
from rest_framework.utils import json


class ApiRenderer(BaseRenderer):

    def render(self, data, accepted_media_type=None, renderer_context=None):
        response_dict = {
            'status': 'failure',
            'data': {},
            'message': '',
        }
        if data.get('data'):
            response_dict['data'] = data.get('data')
        if data.get('status'):
            response_dict['status'] = data.get('status')
        if data.get('message'):
            response_dict['message'] = data.get('message')
        data = response_dict
        return json.dumps(data)

And then in your settings file:

REST_FRAMEWORK = {
    ...
    'DEFAULT_RENDERER_CLASSES': (
        'app_name.renderers.ApiRenderer',
    ),
    ...
}

By this action all views that extend DRF generic views will use renderer. If
you needed to override setting you can use renderer_classes attribute for
generic view classes and @renderer_classes decorator for api view functions.

A comprehensive renderer class to override is available at
<virtualenv_dir>/lib/python3.6/site-packages/rest_framework/renderers.py.



 类似资料:
  • 问题内容: 使用Django REST Framework,标准的ModelSerializer将允许通过将ID作为整数发布来分配或更改ForeignKey模型关系。 从嵌套序列化程序中获取此行为的最简单方法是什么? 注意,我只在谈论分配现有数据库对象,而不是嵌套创建。 过去,我在序列化程序中使用附加的“ id”字段以及自定义和方法来解决这个问题,但是对我来说,这似乎是一个简单而频繁的问题,我很想

  • 本文向大家介绍Django DRF路由与扩展功能的实现,包括了Django DRF路由与扩展功能的实现的使用技巧和注意事项,需要的朋友参考一下 一. 视图集与路由的使用 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中: list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() 保存数据 destory() 删除数据 ViewSe

  • 本文向大家介绍Django DRF认证组件流程实现原理详解,包括了Django DRF认证组件流程实现原理详解的使用技巧和注意事项,需要的朋友参考一下 视图函数中加上认证功能,流程见下图 在def initial(self, request, *args, **kwargs):函数中找到认证功能 流程总结: dispatch 方法里self.initial里面有个认证组件self.perform_

  • 本文向大家介绍DRF跨域后端解决之django-cors-headers的使用,包括了DRF跨域后端解决之django-cors-headers的使用的使用技巧和注意事项,需要的朋友参考一下 在使用django-rest-framework开发项目的时候我们总是避免不了跨域的问题,因为现在大多数的项目都是前后端分离,前后端项目部署在不同的web服务器上,因为我们是后端程序员,因此我要通过后端的程序

  • 您好,我在Django中有一个项目,它对不同的数据库执行多个查询,并在多个endpoint中返回它们,为此我使用Pandas和DRF(APIViews)。 当响应很长,逻辑上服务器运行内存溢出时,问题就出现了,我知道我需要分页结果,但我没有找到方法,因为我不使用模型或序列化器,我用熊猫做原始查询进行查询。 有没有办法像我这样分页结果? 我留下了一些代码片段。

  • 我有一个模型,它使用一个通用外键,使用“content\u type”字段来存储内容类型,“object\u id”来存储对象id。这个模型需要使用CRUD API进行操作,我使用的是DRF。我有一个模型的序列化程序,但我遇到了一点问题。如果我只是将content\u type添加到如下字段列表中 序列化程序将JSON表示设置为ContentType模型实例的ID。API的用户不知道这些ID,我不