Django Rest Framework 3需要字段行为

Ald*_*und 5 python django django-rest-framework

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

class TestSerializer(serializers.Serializer):
   att1= serializers.CharField()
   att2= serializers.CharField()
   att3= serializers.CharField(required=False) 
Run Code Online (Sandbox Code Playgroud)

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

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

但根据发布说明:

required = False:输入中不需要存在该值

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

 data = TestSerializer(s.get_results()).data
Run Code Online (Sandbox Code Playgroud)

哪里有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
Run Code Online (Sandbox Code Playgroud)

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

Kev*_*own 5

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

很难判断您的情况是序列化还是反序列化数据,但您会发现两者都有问题,因此我将为您提供这两种情况的答案。


反序列化 data 时,您应该传入要使用data关键字参数进行反序列化的数据,以及(可选)要使用关键字参数更新的实例instance

serializer = TestSerializer(data=s.get_results())
if serializer.is_valid():
    data = serializer.data
Run Code Online (Sandbox Code Playgroud)

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

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


序列化 data 时,您需要使用instance关键字参数传递完整的对象表示,这也是第一个位置参数。Django REST Framework 期望传入的对象将具有您请求的所有字段,即使它们是null( None) 或空白。required=False参数在这里没有任何作用,因为我们正在序列化数据。因此,您需要确保字典(或类似对象)与序列化程序所需的所有键一起传入。

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