我已经阅读了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后出现了这个错误。
答案 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期望传入的对象将包含您请求的所有字段,即使它们是null
(None
)或空白。 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
问题解决了。