【问题标题】:Rename response fields django rest framework serializer重命名响应字段 django rest 框架序列化程序
【发布时间】:2017-01-12 11:25:32
【问题描述】:

我正在使用 djangorestframework 调用一个简单的 get API。我的模型是

class Category(models.Model):
    category_id = models.AutoField(primary_key=True)
    category_name = models.CharField("Category Name", max_length = 30)
    category_created_date = models.DateField(auto_now = True, auto_now_add=False)
    category_updated_date = models.DateField(auto_now = True, auto_now_add=False)

    def __str__(self):
        return self.category_name

serializer.py

class CategorySerializer(serializers.ModelSerializer) :
    class Meta:
        model = Category
        fields = ['category_id', 'category_name']

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        return Response(serializer.data)

当我在 URL 上点击请求并返回以下响应时,它工作正常。

[
    {
        "category_id": 1,
        "category_name": "ABC"
    }
]

我想更改响应字段名称,因为它仅适用于我的数据库,并且不想在响应中披露。如果我在序列化程序类中更改名称,则不会出现字段匹配错误。

我还想在响应对象中自定义其他参数,如上面的响应,消息和状态如下所示。

{
status : 200,
message : "Category List",
response : [
        {
            "id": 1,
            "name": "ABC"
        }
    ]
}

需要适当的指导和流程。专家帮助。

【问题讨论】:

标签: python django django-rest-framework jsonserializer


【解决方案1】:

首先在字段名称中使用category_ 是多余的。因为您已经将此字段分配给Category 模型,并且通过这样做,您正在为此字段创建“命名空间”。

class Category(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField("Category Name", max_length = 30)
    created_date = models.DateField(auto_now = True, auto_now_add=False)
    updated_date = models.DateField(auto_now = True, auto_now_add=False)

    def __str__(self):
        return self.name

第二在 django id AutoField 是自动创建的,为什么需要显式设置?

并回答您的问题序列化器字段中有source 参数。

class CategorySerializer(serializers.ModelSerializer):
    renamed_id = serializers.IntegerField(source='category_id')
    renamed_name = serializers.CharField(source='category_name')

    class Meta:
        model = Category
        fields = ['renamed_id', 'renamed_name']

您可以手动更改您的回复

from rest_framework import status

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        response = {
            'status': status.HTTP_200_OK,
            'message' : "Category List",
            'response' : serializer.data
        }
        return Response(response)

【讨论】:

  • 试过,但它给出了 AssertionError:字段 'renamed_id' 已在序列化器 CategorySerializer 上声明,但尚未包含在 'fields' 选项中。
  • 您只需更改Meta 中的fields 参数即可。查看更新的答案。
  • 工作。谢谢你。你能告诉我哪个是编写自定义响应代码的最佳实践吗?我的意思是写在 serializers.py 或 views.py 中?
  • 这取决于您要达到的目标。最好的方法是编写基于类的视图,它可以被子类化以供重用。
  • 它适用于获取请求,但是当我对 PUT 运行 curl 请求时,它失败 curl -X PUT localhost:8000/api/add-category/4 -d "category_name=xyz" 它适用于PUT 当我不重命名字段时
【解决方案2】:

您可以在序列化程序中覆盖 to_representation 函数。检查以下代码您可以根据需要更新 data 字典。

class CategorySerializer(serializers.ModelSerializer) :
    class Meta:
        model = Category
        fields = ['category_id', 'category_name']
    def to_representation(self, instance):
        data = super(CategorySerializer, self).to_representation(instance)
        result_data={"status" : 200,"message" : "Category List"}
        result_data["response"]=data
        return result_data

【讨论】:

  • 它在每个对象中添加 [ { "status": 200, "message": "Category List", "response": { "category_id": 1, "category_name": "Educational News" } }, { "status": 200, "message": "Category List", "response": { "category_id": 2, "category_name": "死亡新闻" } }, ]
【解决方案3】:

您可以将其封装在json 中。这就是你想要的渲染方式:

from django.http import HttpResponse
import json

def category_list(request):
    if request.method == 'GET':
        categories = Category.objects.all()
        serializer = CategorySerializer(categories, many=True)
        response = {'code: 200, 'message': 'Category List', 'response': serializer.data}
        return HttpResponse(json.dumps(response), mimetype='application/json')

这是您可以重命名字段的方式:

class CategorySerializer(serializers.ModelSerializer):
    name = serializers.CharField(source='category_name')

    class Meta:
        model = Category
        fields = ['category_id', 'name']

这是docs,用于使用不同的名称进行序列化。

【讨论】:

  • 现在它给了我以下错误文件“/Users/smartSense/Pinank/Django/Work/MadhaparDemo/MadhaparDemo/Category/urls.py”,第 3 行,在 from .views import category_list文件“/Users/smartSense/Pinank/Django/Work/MadhaparDemo/MadhaparDemo/Category/views.py”,第 15 行响应 = {'code:200,'message':'Category List',响应:serializer.data}
  • @PinankLakhani 很抱歉,我改变了那条线,试试看
  • 工作但我仍然无法导入 simplejson。我也想重命名字段名称
  • @PinankLakhani 你用json 包(更新答案)来做到这一点。重命名字段是什么意思?您可以在序列化程序中执行此操作
  • 试过,但它给出了 AssertionError:字段“名称”已在序列化器 CategorySerializer 上声明,但未包含在“字段”选项中。
【解决方案4】:

在 Django 2.1.1 中,如果您使用的是视图集,您可以像这样覆盖 .list() 操作来自定义响应的其他部分

from rest_framework import status
from django.http import HttpResponse
import json

class CategoryViewset(viewsets.ReadOnlyModelViewSet):
    categories = Category.objects.all()

    def list(self, request):
        if request.method == 'GET':
            serializer = CategorySerializer(self.categories, many=True)
            response = {
                'status': status.HTTP_200_OK,
                'message' : "Category List",
                'response' : serializer.data,
            }
            return HttpResponse(json.dumps(response), content_type='application/json')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2015-09-01
    • 2014-11-25
    • 2019-10-26
    相关资源
    最近更新 更多