【问题标题】:Alter the parameter name during serialization在序列化期间更改参数名称
【发布时间】:2020-08-27 03:35:21
【问题描述】:

我在使用 DRF 进行序列化期间更改参数名称时遇到了困难。

我的输入是带有一些参数的 JSON:

{
"limit": 10,
"type": "group",
[...]
}

我的序列化器看起来像:

class RankSerializer(serializers.Serializer):

    limit = serializers.IntegerField(default=100, min_value=1)
    type = serializers.CharField()

    def validate_type(self, t):
        # validation

但这听起来不对。 Type 是 Python 中的保留关键字,因此我不想将其用作参数名称。我想以某种方式将其映射到即 result_type 或类似的东西。 我已经尝试使用 source= 参数如下:

result_type = serializers.CharField(source='type')

但这似乎不适用于非模型输入。

我无法在前端级别重命名参数。

如果能提供有关此问题的任何提示,我将不胜感激。干杯。

【问题讨论】:

标签: django python-2.7 django-rest-framework


【解决方案1】:

我搜索了 DRF 文档的 https://www.django-rest-framework.org/api-guide/fields/,但找不到可行的解决方案。所以我继承了 DRF 提供的 Serializer 类并创建了一个 CustomSerializer。在那,我继承了 run_validation 方法。在那,在调用 super().run_validation() 之前,我访问传递的 initial_data 并将其更改为您提到的所需映射。我存储在嵌套在 RankSerializer 内的 Meta 类中的字段映射信息。因此,例如,您有字段 F1、F2、F3(例如,在 JSON 数据中)其值要填充到名为 M1、M2、M3 的字段中,您只需在 field_mappings 字典的 Meta 类中编写以下内容:

field_mappings = {
'M1': 'F1', 
'M2':'F2', 
'M3': 'F3'
}

其他字段将正常运行。 这是代码

import rest_framework.serializers as serializers
from .models import Rank
from rest_framework.fields import empty

class CustomSerializer(serializers.Serializer):
    def run_validation(self, data=empty):
        for (field, mapping) in self.Meta.field_mappings.items():
            data[field] = data[mapping]
            del data[mapping]
        return super().run_validation(data=data)

class RankSerializer(CustomSerializer):
    limit = serializers.IntegerField(default=100, min_value=1)
    result_type = serializers.CharField(required=True)
    class Meta:
        field_mappings = {
            'result_type': 'type'
        }
    def create(self, validated_data):
        print(validated_data)
    def update(self, instance, validated_data):
        print(validated_data)



'''
Please run the code below in the InteractiveShell to verify the result

from myapp.serializers import RankSerializer
serializer = RankSerializer(data={"limit":15, "type":"Hello"})
serializer.is_valid()
'''

在多行 cmets 中运行代码验证结果后这里是快照

【讨论】:

    【解决方案2】:

    我找到的解决方法是修改validate方法中的参数名称如下:

    def validate(self, data):
        data = super(RankSerializer, self).validate(data)
        data['result_type'] = self.validate_result_type(self.initial_data.get('type'))
        return data
    

    不确定这是否是最干净的方法,但我更喜欢它而不是 @punter147 答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-20
      • 2010-10-13
      • 2019-05-02
      相关资源
      最近更新 更多