博客五部曲之三 - 博客RESTful


1266 浏览 5 years, 2 months

29 UserLogin API Validation

版权声明: 转载请注明出处 http://www.codingsoho.com/

UserLogin API Validation

这一节我们会验证密码有效性,email匹配等。

登陆的时候我们可以选择用用户名验证或者邮箱地址登陆,这些都是常见的登陆方式。
所以需要将username和email的字段设为required=False, allow_blank=True,但是不需要同时为空,后面validate里执行这个验证。

class UserLoginSerializer(ModelSerializer):
    token = CharField(allow_blank=True, read_only=True)
    username = CharField(required=False, allow_blank=True)
    email = EmailField(label='Email Address',required=False, allow_blank=True)  
    def validate(self, data):
        user_obj = None
        email = data.get('email', None)
        username = data.get('username', None)
        password = data.get('password', None)
        if not email and not username:
            raise ValidationError("A username or email is required to login.")
        user_qs = User.objects.filter(
            Q(email=email) | 
            Q(username=username) ).distinct()
        user_qs = user_qs.exclude(email__isnull=True).exclude(email__iexact="")
        if user_qs.exists() and user_qs.count() == 1:
            user_obj = user_qs.first()
        else:
            raise ValidationError("This username/email is not valid.")
        if user_obj:
            if not user_obj.check_password(password):
                raise ValidationError("Incorrent credentials please try again.")
        data["token"] = "SOME RANDOM TOKEN"
        return data 

user_qs = user_qs.exclude(email__isnull=True).exclude(email__iexact="") 这一句的作用是过滤掉那些邮箱地址为空的,因为这个字段不是必填的,所以如果用用户名登陆的话,email字段为空,那么这些用户都会被匹配,必须将它们去掉

返回的token值可以在permission_class这些地方使用