Django Rest Framework 3需要字段行为

时间:2014-12-22 13:27:31

标签: python django django-rest-framework

我已经阅读了drf3的更新日志,但对我来说仍然不清楚。 以前我有以下序列化器:

class TestSerializer(serializers.Serializer):
   att1= serializers.CharField()
   att2= serializers.CharField()
   att3= serializers.CharField(required=False) 

当我传递只有att1和att2值的对象时 - 它工作正常,没有错误,输出中没有属性。但现在,如果我不通过att3我得到错误

  

尝试在序列化程序att3上获取字段TestSerializer的值时获得KeyError   序列化程序字段可能名称不正确,并且与EasyDict实例上的任何属性或键都不匹配   原始异常文本是:att3'。

但根据发行说明:

  

required = False:输入

中不需要存在该值

所以代码似乎对我有用或者我不明白。

 data = TestSerializer(s.get_results()).data

其中get_results的EasyDict实例缺少att3:

class EasyDict(dict):

  def __init__(self, d=None, **kwargs):
    if d is None:
        d = {}
    if kwargs:
        d.update(**kwargs)
    for k, v in d.items():
        setattr(self, k, v)
    # Class attributes
    for k in self.__class__.__dict__.keys():
        if not (k.startswith('__') and k.endswith('__')):
            setattr(self, k, getattr(self, k))

  def __setattr__(self, name, value):
    if isinstance(value, (list, tuple)):
        value = [self.__class__(x) if isinstance(x, dict) else x for x in value]
    else:
        value = self.__class__(value) if isinstance(value, dict) else value
    super(EasyDict, self).__setattr__(name, value)
    self[name] = value

它在drf2中工作得很好,但在升级到drf3后出现了这个错误。

2 个答案:

答案 0 :(得分:4)

Django REST Framework使用序列化程序来序列化(输出)和反序列化(输入)数据。

很难说你是在序列化还是反序列化你的数据,但是你会发现两者都有问题,所以我会给你两个案例的答案。


反序列化数据时,应使用data关键字参数传入数据以反序列化,并(可选)使用instance关键字参数更新实例

serializer = TestSerializer(data=s.get_results())
if serializer.is_valid():
    data = serializer.data

这应该按预期工作,直到您在序列化程序上调用.data。这是因为调用.data然后将根据临时实例再次序列化数据对象,您将在下面学习它仍然是一个问题。

重要的是要注意反序列化数据时,required=False参数将阻止Django REST Framework要求该字段存在。


序列化数据时,需要使用instance关键字参数传递完整的对象表示,该参数也是第一个位置参数。 Django REST Framework期望传入的对象将包含您请求的所有字段,即使它们是nullNone)或空白。 required=False参数在此处不执行任何操作,因为我们正在序列化数据。因此,您需要确保使用序列化程序所需的所有键传入字典(或类似对象)。 / p>

但是,当一个对象被反序列化然后使用同一个对象序列化时,有一种特殊情况。在这种情况下,已创建的基础对象仍必须具有可选字段,即使输入未提供该字段。

答案 1 :(得分:0)

我点击同样的事情,查看代码内部并阅读文档,我发现:

http://www.django-rest-framework.org/api-guide/serializers/#inspecting-a-modelserializer

  

序列化多个对象

     

序列化查询集或对象列表而不是单个对象   例如,在实例化时应该传递many = True标志   串行器。

2.x的代码是:

  

CollectionSerializer(集合)。数据

更改为:

  

CollectionSerializer(collections,many = True).data

问题解决了。