在我的应用程序中,有一个模型将配置存储在其中一个字段中。字段定义为JSONField
。我有一个严格的结构来定义这个字段的内容应该是什么样子,但是我正在努力寻找一种方法来序列化它来验证API请求中的数据。在
目前有效的解决方案是盲目接受符合json
对象的任何内容,但不验证config_field
内部的内容:
我的模型的简化版本:
class MyModel(models.Model):
config_field = JSONField(...)
...
对于这个问题,这里是存储在config_field
中的数据结构的简化版本:
下面是我的序列化程序的简化版本:
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
在请求的主体中,则应该提供整个嵌套对象。在
您正在发送针对
config_field
字段的数据,因此,您的数据应该包含该键。所以有效载荷应该如下所示更新-1
在序列化程序中使用
^{pr2}$DictField()
在尝试了几种可能的解决方案后,我想指出两个最简单也是最重要的解决方案,即不需要对
MyModelSerializer
或内部序列化程序重写create
方法:MyModelSerializer
中config_field
的字段验证方法MyModelSerializer
序列化的整个对象的validate
方法表示
config_field
内部内容的序列化程序对于这两个解决方案是相同的:解决方案1
重写
^{pr2}$MyModelSerializer
中config_field
的字段验证方法。在给定的示例中,序列化程序的最终代码为:此方法首先使用默认的
JSONFieldSerializer
验证config_field
,如果内容不是有效的JSON
对象,则引发异常。在如果
JSONFieldSerializer
不引发异常,则调用validate_custom_fields
,并将字段的内容传递到ConfigFieldsSerializer
中,并为自身和所有嵌套序列化程序验证所有内容。在解决方案2
重写由
MyModelSerializer
序列化的整个对象的validate
方法。在给定的示例中,序列化程序的最终代码为:这种方法需要多一点代码,但允许将
config_field
的验证与其他相关字段相结合。在相关问题 更多 >
编程相关推荐