Python DRF-如果任何定义的字段为“无”,则引发异常

Python DRF-如果任何定义的字段为“无”,则引发异常,python,django,django-models,django-rest-framework,Python,Django,Django Models,Django Rest Framework,我需要将模型序列化为JSON。然后将此JSON发送到一个API 但此API要求某些字段不能为“无” 我有这些字段的列表。在这种情况下,让我们假设它只是[电话],但它可以更多 例如: class UserSerializer(serializers.ModelSerializer): telephone = serializers.CharField(source='userprofile.telephone') class Meta: model = User

我需要将模型序列化为JSON。然后将此JSON发送到一个API

但此API要求某些字段不能为“无”

我有这些字段的列表。在这种情况下,让我们假设它只是[电话],但它可以更多

例如:

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需要一些字段,比如电话,所以我希望UserSerializer在所需字段为None时引发ValidationError

所以在本例中,我无法序列化用户,因为电话是空的

我尝试了很多方法,包括在电话中添加required=True,但没有任何效果


是否有方法验证序列化数据?请注意,我不是在谈论反序列化。

您不需要这样做。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)

您需要的不是验证数据是否可以反序列化,而是验证数据是否可以序列化。诸如required=True之类的表达式都用于验证数据以进行反序列化。序列化在序列化程序类的to_表示方法中处理,该类是ModelSerializer的基础

您可以做的是,重写为_表示,如果必填字段值为None,则让该方法引发异常

您可能需要进一步将默认DRF类(如序列化器字段的字段)子类化,并使用自定义类以系统方式提供功能。对此,您不希望依赖required=True,因为它已用于反序列化验证的另一个目的

我的建议是,为Field类创建子类,添加一个属性,如required_for_read,并使用自定义Field类使用此属性定义序列化器字段。然后,在重写为_的表示方法中,查找此属性,如果字段的此属性为True,但其值为None,则引发异常

为什么验证不起作用? 验证过程仅在反序列化过程输入是类似dict的对象并且您正在尝试序列化过程时进行。在序列化的情况下,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_表示方法


为什么要尝试required=False而不是required=True?这是一个错误类型。当然我试过了required=True:谢谢,但是什么是用户数据呢。我想序列化模型。此外,我不能对任何只读字段(如SerializerMethodField)使用required=True,因此您需要使用serializers.ModelSerializer,而不是MethodSerializer.user_数据只是任何具有创建模型实例所用信息的通用dict。
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