在这里完成DRF初学者......我对以下概念感到困惑:
让我们说一些数据,包括其中一个字段的复杂JSON blob,以便创建一个对象。我应该在哪里创建这个对象?看看3.1文档,看起来两个地方对此同样有效:Serializer.create()和ViewSet.create()。我如何决定在哪里创建我的对象以及考虑哪种方式"规范"?
我知道我需要运行Serializer.is_valid()才能验证POSTed数据。但是,.data和.validated_data之间有什么区别?它们看起来是一样的。
最后,什么是"规范"使用JSONField的方法(例如django-jsonfield,但我没有与这个包/实现结合)?我有一个带有几个JSONFields的模型,并希望正确使用它#34;正确"在DRF。我知道https://stackoverflow.com/a/28200902/585783,但它似乎不够。
编辑:我的用例是一个API POST,其中包含一个字段中的复杂JSON blob。我需要解析JSON字段,验证它,基于它获取/创建多个对象,链接新对象和现有对象,最后将JSON字段存储在其中一个新对象中。因此,我需要通过将其解析为python来对此JSON字段进行自定义验证:
from django.utils.six import BytesIO
from rest_framework.parsers import JSONParser
class MySerializer(serializers.ModelSerializer):
my_json_field = JSONSerializerField()
def validate_my_json_field(self, value):
stream = BytesIO(value)
list_of_dicts = JSONParser().parse(stream)
# do lots of validation to list_of_dicts
# render list_of_dicts back to a JSON string
return validated_list_of_dicts_as_json
现在,根据我在概念1中选择的方式,我必须再次解析经过验证的JSON以在create()中创建我的对象,这感觉不对。
提前致谢!
答案 0 :(得分:3)
HTTP请求(POST,GET,PUT,DELETE)的内容将始终由视图(View,APIView,通用视图,视图集)处理。序列化程序只是这些视图处理请求的一部分。序列化程序是将View层与Model层连接的“手段”。有关序列化程序的具体内容,请阅读此page官方文档的第一段。
回答#1:除非你有一个非常具体的用例,否则你几乎总是不需要触摸它们。在那些特殊情况下:
Serializer.create()
实例转换为本机Python对象,反之亦然。 (例如创建多个对象)ViewSet.create()
。 (例如,如果请求中有其他查询参数,请添加一些响应标头)要回答#2,在使用通用视图或ViewSet时几乎不需要使用is_valid()
。他们已经为你做了它。序列化程序的.data
和.validated_data
有点难以解释。前者包含要序列化的查询集/模型实例的Python数据类型表示,而后者是验证过程涉及检查Python对象是否符合前面提到的特定Python数据类型表示的结果,而后者又可以是转换为模型实例。如果这没有意义,请参阅Serializing objects和Deserializing objects。
至于#3,JSON字段是什么意思?据我所知,Django没有名为JSONField的模型字段。这是来自第三方软件包还是您自己的自定义书面模型字段?如果是这样,那么您可能必须找到或编写一个包,让您可以顺利地“正确”地将它与DRF集成。
修改强>
你的用例太复杂了。我只能给你这个粗略的代码。
class MyModelSerializer(serializers.ModelSerializer):
my_json_field = JSONSerializerField()
class Meta:
model = MyModel
def validate(self, data):
# Get JSON blob
json_blob = data['my_json_field']
# Implement your own JSON blob cleanup method
# Return None if invalid
json_blob = clean_json_blob(json_blob)
# Raise HTTP 400 with your custom error message if not valid
if not json_blob:
raise serializers.ValidationError({'error': 'Your error message'})
# Reassign if you made changes and return
data['my_json_field'] = json_blob
return data
def create(self, validated_data):
json_blob = validated_data['my_json_field']
# Implement your object creation here
create_all_other_objects_from_json(json_blob)
# ...
# Then return a MyModel instance
return my_model