Python DRF:提交详细路由的POST请求时序列化程序验证

Python DRF:提交详细路由的POST请求时序列化程序验证,python,django,validation,django-rest-framework,Python,Django,Validation,Django Rest Framework,这里是DRF新手。我有以下型号: class User(models.Model): first_name = models.CharField(max_length=30, null=True, blank=True) last_name = models.CharField(max_length=30, null=True, blank=True) email = models.EmailField(max_length=254, null=False, blan

这里是DRF新手。我有以下型号:

class User(models.Model):

    first_name = models.CharField(max_length=30, null=True, blank=True)
    last_name = models.CharField(max_length=30, null=True, blank=True)

    email = models.EmailField(max_length=254, null=False, blank=False, unique=True)
    password = models.CharField(max_length=128, null=False, blank=False)
我成功地实现了
POST/users/
。我能够根据预定义的约束验证请求正文中的
密码
电子邮件
字段。(例如,密码不能完全是数字)。为此,我覆盖字段验证器,例如
验证密码
验证电子邮件

现在,我正在尝试实现一个端点
POST/users/pk/password/
,通过该端点,用户可以更新其
密码
资源。为了实现这一点,我使用了
detail\u route
。您可以在下面找到相应的实现:

# Custom method to update the password resource of a given user.
@detail_route(methods=['post'])
def password(self, request, pk=None):

    try:
        user = User.objects.get(pk=pk)
    except User.DoesNotExist:
        # returns error
    else:

        password = request.data.get('password',None)
        new_password = request.data.get('new_password',None)

        if password and new_password:

            if check_password(password,user.password):

                # Use Django built-in to hash password.
                password_hash =  make_password(new_password)
                user.password = password_hash
                user.save()

                serializer_data = UserSerializer(user).data

                return Response(serializer_data)

            else:
                # return error reponse
        else:
            # return error response
通过使用这种方法,我能够更新用户的
密码
字段,但是当调用
POST/users/pk/password/
时,
validate\u password
不再有效,因此用户可以用一个完全数字的密码更新他们的
密码

我知道我可以尝试在细节路由实现中实现
validate\u password
,但这并不是最好的方法

我的问题是,在不复制代码和不将验证逻辑移动到views.py的情况下,最好的方法是什么

PS:由于各种原因,我不能使用或扩展Django用户模型


谢谢

这就是问题所在,当您应该使用序列化程序时,您直接从原始文章中获取数据

    password = request.data.get('password',None)
    new_password = request.data.get('new_password',None)
现在假设带有验证代码的序列化程序名为
MySerializer
,则需要将上面的行替换为

   serial = MySerializer(data=request.data)
   if serial.is_valid():
       password = serial.validated_data['password']
       new_password = serial.validated_data['new_password']

现在将执行您的验证代码。

谢谢!有道理。但当我这样做时,由于电子邮件等必填字段,序列化程序验证失败。电子邮件是创建用户所必需的字段,但在更新密码时不是必需的。如何克服这个问题?不要害怕创建多个序列化程序。很多新手都会犯这样的错误。为密码字段创建一个新的序列化程序。