Django 序列化程序:未调用验证函数

Posted

技术标签:

【中文标题】Django 序列化程序:未调用验证函数【英文标题】:Django serializers: validate function not called 【发布时间】:2016-08-11 04:07:38 【问题描述】:

我正在尝试覆盖 validate() 函数以由 serializers.is_valid() 调用,但它没有被调用。

serializer.py

class LoginSerializer(serializers.Serializer):
    email = serializers.EmailField(max_length=255,required=True)
    password = serializers.CharField(max_length=128,required=True)


    def validate(self,data):
       '''
       Check for invalid email.
       & blank email and password. 
       '''

       print 'hey i am in login'

       if data['email'] is '':
           raise serializers.ValidationError("Email cannot be empty.")
       if data['password'] is '':
          raise serializers.ValidationError("Password cannot be empty.")
       try:
          validate_email(data['email'])
       except ValidationError:
          raise serializers.ValidationError("The email is not a valid email address.")
       return data

views.py

class LoginAPI(APIView):
    permission_classes = (permissions.AllowAny,)
    serializer = LoginSerializer

    def post(self, request):
       data = self.serializer(data=request.data)
       if data.is_valid():
          #do something
       else:
           return Response(data.errors,status=status.HTTP_400_BAD_REQUEST)

当我调用is_valid() 时,validate() 函数内的打印语句没有被执行。 我做错了什么?

【问题讨论】:

POST 请求中传递了什么数据? "email":"xyz","password":"" 【参考方案1】:

我认为您没有收到任何 print 语句,因为未调用 validate 函数。

如果其中一个字段出现错误,例如 email,则不会调用 validate 函数,但由于您没有将 raise_exception=True 作为参数传递给 is_valid,因此您不会收到这些错误,并且你假设is_valid 没有运行。

您可以编写post 方法如下:

def post(self, request):
   serializer = self.serializer(data=request.data)

   # following will automatically raise an exception if the serialize data is not valid
   serializer.is_valid(raise_exception=True)

   # do something if the serializer is valid

更新:如果您想在验证不同字段后引发特定消息,您可以在序列化程序中创建一个方法validate_<fieldname>

def validate_email(self, value):

    if value == '':
        raise serializers.ValidationError("Email cannot be empty.")

    try:
        validate_email(value)
    except ValidationError:
        raise serializers.ValidationError("The email is not a valid email address.")

    return value

【讨论】:

我尝试使用serializer.is_valid(raise_exception=True) 但不起作用,你是对的“如果其中一个字段有错误说电子邮件,验证功能将不会被调用”但这就是我正在尝试的捕捉和报告正确的信息 什么不完全有效?我认为它会引发异常,因为您传递的电子邮件,即xyz 不是有效的电子邮件。 我想避免自动处理无效的电子邮件 ID。并放置自定义错误消息。 您可以像在更新的答案中一样使用validate_email 函数。由于 validate_email 将在验证器本身之前被调用,因此您将首先收到自定义错误消息。 仅在email = serializers.EmailField(max_length=255,allow_blank=True)时有效,仅在传递空白时捕获。但对于任何无效值 xyz,它会自动处理【参考方案2】:

我有同样的错误。试试看

def run_validation(self, data):
...

而不是

def validation(self, data):
...

这应该可行!

【讨论】:

以上是关于Django 序列化程序:未调用验证函数的主要内容,如果未能解决你的问题,请参考以下文章

python Django Rest_Framework框架 反序列化时数据校验的三种方法(图文并茂版)

Django 表单验证与 DRF 序列化程序验证

如何在 Django 中序列化(JSON)文件字段

是否可以在 django rest 框架序列化程序中使用重用 django 表单进行验证?

Django REST Framework:嵌套序列化程序未出现

护照反序列化用户未在帆中调用