【问题标题】:DRF: Serializer validation while submitting a POST request to detail routeDRF:在提交 POST 请求以详细路由时进行序列化程序验证
【发布时间】:2017-06-06 20:07:19
【问题描述】:

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/。我能够根据预定义的约束验证请求正文中的passwordemail 字段。(例如,密码不能完全是数字)为此,我覆盖了validate_passwordvalidate_email 等字段验证器。

现在我正在尝试实现一个端点POST /users/pk/password/,用户可以通过它更新他们的password 资源。为此,我使用了detail_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

通过使用这种方法,我可以更新用户的password 字段,但是当调用POST /users/pk/password/validate_password 不再有效,以便用户可以使用完全数字的password 更新他们的password .

我知道我可以尝试在详细路由实现中实现validate_password,但这并不是最好的方法。

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

PS:由于各种原因,我无法使用或扩展 Django 用户模型。

谢谢!

【问题讨论】:

    标签: python django validation django-rest-framework


    【解决方案1】:

    这个问题,当你应该使用序列化器时,你直接从原始帖子中获取数据

        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']
    

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

    【讨论】:

    • 谢谢!说得通。但是当我这样做时,由于电子邮件等必填字段,我在序列化程序验证中失败了。电子邮件是创建用户的必填字段,但在更新密码时不是必需的。我该如何克服这个问题?
    • 不要害怕制作多个序列化器。很多新手都会犯这个错误。为密码字段创建一个新的序列化程序。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-05
    • 1970-01-01
    • 2016-12-20
    • 2020-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多