为了账号安全,请及时绑定邮箱和手机立即绑定

DRF - 如果任何定义的字段为 None 则引发异常

DRF - 如果任何定义的字段为 None 则引发异常

汪汪一只猫 2021-12-26 15:17:36
我需要将模型序列化为JSON. 然后将其发送JSON给 one 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因为telephoneis None。我尝试了很多事情,包括添加required=True到,telephone但没有任何效果。有没有办法validate序列化数据?请注意,我不是在谈论deserialization.
查看完整描述

3 回答

?
凤凰求蛊

TA贡献1825条经验 获得超4个赞

为什么验证不起作用?

验证过程仅在Deserializationprocess(输入是一个dict类似的对象)并且您正在尝试Serializationprocess 时进行。在 的情况下Serialization,DRF 假定给定对象是有效对象,因此不需要验证。


源DRF 串行器


我们怎样才能做到这一点?

方法 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


查看完整回答
反对 回复 2021-12-26
?
暮色呼如

TA贡献1853条经验 获得超9个赞

您想要的不是验证数据以进行反序列化,而是验证序列化。像required=True这样的表达式都用于验证数据以进行反序列化。序列化在Serializer类的to_representation方法中处理(这是ModelSerializer的基础)

您可以做的是,覆盖to_representation,并在必填字段值为 None 时让该方法引发异常。

您可能需要进一步子类化默认 DRF 类,如Field(用于序列化程序字段),并使用您的自定义类能够以系统的方式提供您的功能。您不想为此依赖required=True,因为它已经用于其他目的(用于反序列化验证)。

我的建议是,子类Field类,添加一个类似“ required_for_read ”的属性,并使用您的自定义字段类定义带有此属性的序列化程序字段。然后,在您重写的to_representation方法中,查找此属性,如果该字段的此属性为True但其值为None则引发异常


查看完整回答
反对 回复 2021-12-26
?
白衣染霜花

TA贡献1796条经验 获得超10个赞

你不需要。DRF 序列化器可以立即执行此操作。如果某个字段设置为null=Falseor 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)


查看完整回答
反对 回复 2021-12-26
  • 3 回答
  • 0 关注
  • 199 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信