Python 如何自定义用户名验证

Python 如何自定义用户名验证,python,django,Python,Django,我正在尝试为用户模型自定义用户名验证。它说用户名可能包含字母数字、u、@、+、。和-字符。但我想这样做,如果用户使用@、、-、+创建用户名,则该用户名无效。我如何覆盖此验证,以便用户创建用户名时使用我的自定义验证,而不是原始的UnicodeSerNameValidator 我使用自己的自定义用户模型,但我继承自AbstractBaseUser是否有简单的方法添加我的用户名验证?可以在模型类上设置一个属性: 指向用于验证用户名的验证程序实例。默认为验证器。UnicodeSerNameValidat

我正在尝试为用户模型自定义用户名验证。它说
用户名可能包含字母数字、u、@、+、。和-字符。
但我想这样做,如果用户使用
@、、-、+
创建用户名,则该用户名无效。我如何覆盖此验证,以便用户创建用户名时使用我的自定义验证,而不是原始的
UnicodeSerNameValidator

我使用自己的自定义用户模型,但我继承自
AbstractBaseUser
是否有简单的方法添加我的用户名验证?

可以在模型类上设置一个属性:

指向用于验证用户名的验证程序实例。默认为
验证器。UnicodeSerNameValidator

要更改默认用户名验证程序,您可以将
用户
模型子类化,并将此属性设置为其他验证程序实例。例如,要使用ASCII用户名:

from django.contrib.auth.models import User
from django.contrib.auth.validators import ASCIIUsernameValidator

class CustomUser(User):
    username_validator = ASCIIUsernameValidator()

@字节这是一个肮脏的把戏,但有效:-

def loginup(request):
    if request.method == "POST":
        username = request.POST['username']
        password = request.POST['password']

        #Manual code to Check whether username is valid or not
        try:
         myuser = User.objects.get(username=username)
        except:
            myuser = False

        if myuser == False:
            mypass = False
        else:
            mypass = myuser.check_password(password)
        user = auth.authenticate(username=username, password=password)
        if myuser != False:
            if user is not None:
                auth.login(request, user)
                messages.success(request, "You have Successfully Logged in")
                return render(request, 'index.html')
            else:
                messages.error(request, "Invalid Password")
                return render(request, 'index.html')
        else:
            messages.error(request, "Invalid Username")
            return render(request, 'index.html')
    return render(request, 'index.html')

假设您正在使用用户应用程序,自定义用户模型的名称为
CustomUser
,位于users/models.py中。如果您不想在用户名中允许
@、、-、+
,请创建一个forms.py,如下所示:

用户/forms.py

从django.contrib.auth.forms导入UserCreationForm、UserChangeForm
from.models导入CustomUser
类CustomUserCreationForm(UserCreationForm):
类元(UserCreationForm.Meta):
模型=自定义用户
字段=('username'、'first\u name'、'last\u name'、'email')
def清洁(自清洁):
cleaned_data=super(CustomUserCreationForm,self).clean()
username=已清理的数据。获取('username')
如果用户名中有('@','.','-','+'):
self.add_错误(“用户名”中不允许有“@/-/+符号”。)
返回已清除的数据
#UserChangeForm也是如此
类CustomUserChangeForm(UserChangeForm):
类元(UserChangeForm.Meta):
模型=自定义用户
字段=('username'、'first\u name'、'last\u name')
#删除电子邮件字段。任何人都不想在注册后更改电子邮件。随你的便。
def清洁(自清洁):
cleaned_data=super(CustomUserChangeForm,self).clean()
username=已清理的数据。获取('username')
如果用户名中有('@','.','-','+'):
self.add_错误(“用户名”中不允许有“@/-/+符号”。)
返回已清除的数据
如果有人试图在用户名中使用
@、、-、+
注册,则将显示您的自定义错误消息

更改Django默认描述
是必需的。150个字符或更少。字母、数字和@/+/-/\uOnly.
,您的models.py应该如下所示:

用户/型号.py

从django.contrib.auth.models导入AbstractUser
从django.db导入模型
从django.contrib.auth导入get\u user\u模型
从django.contrib.auth.validators导入UnicoduerNameValidator
用户=获取用户模型
类CustomUser(AbstractUser):
用户名\验证器=UnicoduerNameValidator()
用户名=models.CharField(
“用户名”,
最大长度=150,
唯一=正确,
help_text=(“必需。150个字符或更少。仅限字母和数字。”),
#根据需要自定义上述字符串
验证程序=[用户名\验证程序],
错误消息={
“唯一”:(“具有该用户名的用户已存在。”),
},
)
email=models.EmailField(最大长度=254,空白=False,唯一=True)
first_name=models.CharField(最大长度=30,空白=False)
last_name=models.CharField(最大长度=50,空白=False)
另外,不要忘记检查您的视图.py和模板

用户/视图.py

从django.contrib.messages.views导入成功消息
从django.url导入反向链接
从django.views.generic导入CreateView
从.forms导入CustomUserCreationForm
from.models导入CustomUser
...
#在这里创建您的视图。
类注册视图(successessagexin,CreateView):
form\u class=CustomUserCreationForm
成功\u url=reverse\u lazy('login'))
模板名称='signup.html'
成功消息='已成功创建帐户!现在使用您的详细信息登录。”
...
users/templates/signup.html

。。。
{%block content%}
注册
{%csrf_令牌%}
{{form.as_p}}
注册
{%endblock内容%}
...
这是您必须使用的最小HTML。然后一切都会按照你的意愿进行


您可以添加更多自定义项(例如添加Django crispy表单,或用户名/电子邮件中不区分大小写,或避免有时键入
email@gmail.com
email@googlemail.com
。两者都是相同的电子邮件。如果不包含支票,则数据库中会有重复的用户。

因此我可以替换ASCIIUsernameValidator()和我自己的函数?一旦我有了自定义用户名验证程序,它将自动验证用户名,而无需调用任何函数?是的。你为什么不试试呢?我会的!非常感谢你,如果我们制作了
username\u validator=validate\u username()
我们不需要像示例中那样有一个username参数吗?它应该是
username\u validator=validate\u username(username)