gpt4 book ai didi

python - JSONField 嵌套表示的序列化器

转载 作者:太空宇宙 更新时间:2023-11-03 20:56:00 26 4
gpt4 key购买 nike

在我的应用程序中,有一个模型将配置存储在其字段之一中。该字段定义为 JSONField。我有一个严格的结构来定义该字段的内容应该是什么样子,但我正在努力寻找一种方法来序列化它以验证 API 请求中的数据。

目前有效但不验证 config_field 内部内容的解决方案是盲目接受任何符合 json 对象的内容:

我的模型的简化版本:

class MyModel(models.Model):
config_field = JSONField(...)
...

为了解决这个问题,这里有一个存储在 config_field 中的数据结构的简化版本:

{"some_config_int": 42, "some_config_vars": [{"id": 1}, {"id": 2}]}

这是我的序列化器的简化版本:

class MyModelSerializer(serializers.ModelSerializer):
config_field = serializers.JSONField(required=False)
class Meta:
model = MyModel
fields = ('config_field', ...)

我想要实现的是为 config_field 内部内容的嵌套表示( reference to DRF documentation )提供一个序列化器。到目前为止我尝试过的(但不起作用):

class ConfigVarsSerializer(serializers.Serializer):
id = serializers.IntegerField(required=True)

class ConfigFieldsSerializer(serializers.Serializer):
some_config_int = serializers.IntegerField(required=True)
some_config_vars = serializers.ListField(child=ConfigVarsSerializer,required=True)

class MyModelSerializer(serializers.ModelSerializer):
config_field = ConfigFieldsSerializer(required=False)
class Meta:
model = MyModel
fields = ('config_field', ...)

这样,可以选择 POST/PUT 具有配置的对象,但如果 config_field 位于请求正文中,则应提供整个嵌套对象。

最佳答案

在尝试了几种可能的解决方案之后,我想指出 2 个最简单且最重要的解决方案,它们不需要覆盖 create两者都没有的方法MyModelSerializer也不是内部序列化器:

  1. 覆盖 config_field 的字段验证方法在MyModelSerializer
  2. 覆盖validate MyModelSerializer 序列化整个对象的方法

代表 config_field 内部内容的序列化器两种解决方案都是相同的:

class ConfigVarsSerializer(serializers.Serializer):
id = serializers.IntegerField(required=True)

class ConfigFieldsSerializer(serializers.Serializer):
some_config_int = serializers.IntegerField(required=True)
some_config_vars = serializers.ConfigVarsSerializer(required=True, many=True)

Note that some_config_vars stores list of objects, that's why many=True.

<小时/>

解决方案1

覆盖 config_field 的字段验证方法在MyModelSerializer 。在给定示例的情况下,序列化器的最终代码将是:

class MyModelSerializer(serializers.ModelSerializer):
config_field = JSONField(required=False)
class Meta:
model = MyModel
fields = ('config_field', ...)

def validate_config_field(self, value):
serializer = ConfigFieldsSerializer(data=value)
serializer.is_valid(raise_exception=True)
return value

此方法首先验证 config_field使用默认JSONFieldSerializer如果内容不是有效的 JSON ,则会引发异常目的。

如果JSONFieldSerializer也不异常(exception) validate_custom_fields被调用并将字段内容传递到 ConfigFieldsSerializer并验证其自身和所有嵌套序列化器的所有内容。

<小时/>

解决方案2

覆盖validate MyModelSerializer 序列化整个对象的方法。在给定示例的情况下,序列化器的最终代码将是:

class MyModelSerializer(serializers.ModelSerializer):
config_field = JSONField(required=False)
class Meta:
model = MyModel
fields = ('config_field', ...)

def validate(self, attrs):
config_field = attrs.get('config_field')
if config_field:
serializer = ConfigFieldsSerializer(data=config_field)
serializer.is_valid(raise_exception=True)
return attrs

这种方法需要更多的代码,但允许结合 config_field 的验证与其他相关领域。

关于python - JSONField 嵌套表示的序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56025763/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com