我需要将模型序列化为JSON
。然后将此JSON
发送到一个API
。
但是此API
要求某些字段不是None
。
我有这些字段的列表。在这种情况下,我们假设它只是['telephone']
,但可以更多。
例如:
class UserSerializer(serializers.ModelSerializer):
telephone = serializers.CharField(source='userprofile.telephone')
class Meta:
model = User
fields = ['first_name','last_name','telephone']
序列化:
>>> UserSerializer(user).data
>>> {'first_name':'Michael','last_name':'Jackson','telephone':None}
由于API
要求使用telephone
之类的某些字段,因此当所需字段为UserSerializer
时,我希望raise ValidationError
到None
。
因此在这种情况下,我无法序列化user
,因为telephone
是None
。
我尝试了很多事情,包括将required=True
添加到telephone
,但是没有任何效果。
是否有一种方法可以validate
序列化数据?请注意,我并不是在谈论deserialization
。
答案 0 :(得分:1)
仅当Deserialization
过程 (输入是与对象类似的 dict
)时,验证过程才经过 正在尝试 Serialization
进程 。对于 Serialization
,DRF假定给定对象是有效对象,因此不需要验证。
来源DRF-serializers
方法1
使您的用户对象成为user_data(dict
对象),并将其传递给序列化器并运行验证。
user = User.objects.get(id=1)
dict_user_data = {"first_name": user.first_name, "last_name": user.last_name, "telephone": user.userprofile.telephone}
user_serializer = UserSerializer(data=dict_user_data)
user_serializer.is_valid(True)
user_serializer.data
方法2
覆盖 to_representation()
方法
class UserSerializer(serializers.ModelSerializer):
telephone = serializers.CharField(source='userprofile.telephone')
class Meta:
model = User
fields = ['first_name', 'last_name', 'telephone']
def to_representation(self, instance):
data = super().to_representation(instance)
for field, value in data.items():
if value is None:
raise SomeExceptionHere({field: "can't be None"})
return data
答案 1 :(得分:0)
您不需要。 DRF串行器可以立即执行此操作。如果将字段设置为null=False
或required=True
,请执行此操作。
data = UserSerializer(data=user_data)
data.is_valid(raise_exception=True
就是这样。将引发400错误。
如果需要,您可以调整错误消息:
data = UserSerializer(data=user_data)
try:
data.is_valid(raise_exception=True)
except ValidationError as e:
return HttpResponse(status_code=400, content=e)
答案 2 :(得分:0)
您想要的不是验证数据以进行反序列化,而是验证序列化。诸如 required = True 之类的表达式均用于验证数据以进行反序列化。序列化是通过 Serializer 类的 to_representation 方法处理的(这是 ModelSerializer 的基础)
您可以做的是,覆盖 to_representation ,如果必填字段值为None,则使该方法引发异常。
您可能需要进一步子类化默认DRF类,例如 Field (用于序列化器字段),并使用自定义类来系统地提供您的功能。您不想为此依赖 required = True ,因为它已经用于其他用途(用于反序列化验证)。
我的建议是,子类 Field 类,添加一个类似于“ required_for_read ”的属性,并使用自定义字段类使用此属性定义序列化程序字段。然后,在您覆盖的 to_representation 方法中,查找此属性,如果该字段的属性为 True 但其值为 None ,则引发异常>