首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当POSTing在DRF中时,在哪里创建一个对象以及如何有效地验证一个复杂的JSON字段?

当POSTing在DRF中时,在哪里创建一个对象以及如何有效地验证一个复杂的JSON字段?
EN

Stack Overflow用户
提问于 2015-08-04 00:34:47
回答 1查看 600关注 0票数 1

完成DRF初学者在这里..。我对以下概念感到困惑:

  1. 假设我发布了一些数据,包括一个字段的复杂JSON,以便创建一个对象。我应该在哪里创建这个对象呢?看一下3.1docs,似乎有两个地方对此同样有效: Serializer.create()和ViewSet.create()。我如何决定在哪里创建我的对象,哪种方式被认为是“规范”?
  2. 我知道我需要运行Serializer.is_valid()来验证POSTed数据。然而,.data和.validated_data有什么区别呢?他们看起来是一样的。
  3. 最后,使用JSONField的“规范”方式是什么(例如django-jsonfield,但我没有使用这个包/实现)?我有一个带有几个JSONFields的模型,并希望在DRF中“正确地”使用它。我知道https://stackoverflow.com/a/28200902/585783,但这似乎还不够。

编辑:我的用例是一个API帖子,在其中一个字段中包含一个复杂的JSON blob。我需要解析JSON字段,验证它,基于它获取/创建几个对象,链接新的和现有的对象,最后将JSON字段存储在其中一个新对象中。因此,我需要对这个JSON字段进行自定义验证,方法是将它解析为python:

代码语言:javascript
复制
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()中创建我的对象,这感觉不太正确。

提前感谢!

EN

回答 1

Stack Overflow用户

发布于 2015-08-04 05:15:43

HTTP请求(POST、GET、PUT、DELETE)的内容将始终由视图(View、APIView、generic、viewset)处理。序列化程序只是这些视图处理请求的一部分。序列化器是将视图层与模型层连接起来的“手段”。关于序列化器具体做什么,请阅读官方文档的这个页面的第一段。

回答#1:除非您有一个非常具体的用例,否则您几乎总是不需要触摸任何一个。在这些特殊情况下:

  • 如果必须自定义模型实例如何转换为本机Python对象,则重写Serializer.create(),反之亦然。(例如创建多个对象)
  • 如果需要自定义实际请求本身的处理方式,则重写ViewSet.create()。(例如,如果请求中有额外的查询参数,添加一些响应头)

要回答#2,您几乎不需要在使用泛型视图或is_valid()时使用ViewSets。他们已经为你做过了。序列化程序的.data.validated_data解释起来有点棘手。前者包含要序列化的queryset/model实例的Python数据类型表示,而后者是检查Python对象是否符合前面提到的特定Python数据类型表示的验证过程的结果,而后者又可以转换为模型实例。如果这没有意义,请参考序列化对象反序列化对象

至于#3,您所说的JSON字段是什么意思?据我所知,Django没有一个名为JSONField的模型字段。这是来自第三方包还是您自己定制的书面模型字段?如果是这样的话,那么您可能需要找到或编写一个包,使您能够顺利地将其与DRF集成,并“正确地”使用它。

编辑

用例太复杂了。我只能给你这个粗略的代码。

代码语言:javascript
复制
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
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/31798912

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档