python - 显示 django 注册表错误
问题描述
我想在用户尝试注册时显示注册错误,但他做错了一些事情,比如输入现有的电子邮件地址或两个密码不匹配,或者当 django 的默认密码验证器之一不被视为输入短密码时,并且能够使用引导警报设置每个错误的样式,正如我在模板中显示的那样
models.py 中的用户模型
from django.db import models
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
from django.conf import settings
class User(AbstractBaseUser):
email = models.EmailField(verbose_name="Email",max_length=250, unique=True)
username = models.CharField(max_length=30, unique=True, null=True)
date_joined = models.DateTimeField(verbose_name='Date joined', auto_now_add=True)
last_login = models.DateTimeField(verbose_name='Last login', auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
full_name = models.CharField(verbose_name="Full name", max_length=150, null=True)
profile_pic = models.ImageField(null=True, blank=True)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['full_name']
objects = MyAccountManager()
def __str__(self):
return self.full_name
# For checking permissions.
def has_perm(self, perm, obj=None):
return self.is_admin
# For which users are able to view the app (everyone is)
def has_module_perms(self, app_label):
return True
在 views.py 中具有注册/注册表单的视图
def home(request):
user = request.user
# for rendring texts
form = TextForm()
if request.method == "POST":
form = TextForm(request.POST)
if form.is_valid():
obj = form.save(commit=False)
author = User.objects.filter(email=user.email).first()
obj.author = author
form.save()
form = TextForm()
texts = Text.objects.all().order_by('-id')
# for signing in
if request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
elif user is None:
messages.error(request,'ُEmail or password is incorrect')
else:
signin_form = SigninForm()
# for signing up
signup_form = SignupForm()
if request.method == 'POST':
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
User = signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
else:
signup_form = SignupForm()
context = {'signin_form':signin_form,'signup_form':signup_form,'form': form, 'texts': texts}
return render(request, 'main/home.html', context)
我在 forms.py 中的注册表单
class SignupForm(UserCreationForm):
password1 = forms.CharField(widget=forms.PasswordInput(
attrs={'placeholder': 'Password', 'class': 'form-control mt-3'}))
password2 = forms.CharField(widget=forms.PasswordInput(
attrs={'placeholder': 'Confirm your password', 'class': 'form-control mt-3 mb-3', }))
class Meta:
model = User
fields = ("full_name", "email", "password1", "password2")
widgets = {
'full_name': forms.TextInput(attrs={'placeholder': 'Full name', 'class': 'form-control mb-3', }),
'email': forms.EmailInput(attrs={'placeholder': 'Email', 'class': 'form-control', }),
}
在模板中
<div id="signup" class="container tab-pane fade"><br>
<form action="" method="POST">
{% csrf_token %}
{{signup_form.full_name}}
{{signup_form.email}}
{{signup_form.password1}}
{{signup_form.password2}}
<button class="btn btn-success form-control" type="submit">Sign up</button>
{% if signup_form.errors %}
{% for field in signup_form %}
{% for error in field.errors %}
<div class="alert alert-danger alert-dismissible fade show"> {{ error}}
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
{% endfor %}
{% endfor %}
{% endif %}
</form>
我尝试了 form.errors 而不是 signup_form.errors 它呈现了同一模板中另一个表单的错误
解决方案
一旦你调用form.is_valid()
了表单的实例,如果有错误就变得非常重要,因为这些错误存在于那个实例上。因此,您需要将其传回给用户以显示错误。
我的意思的一个简单例子是;
def register(request):
form = CustomUserCreationForm()
if request.method == "POST":
form = CustomUserCreationForm(request.POST)
if form.is_valid():
user = form.save(commit=False)
user.is_valid = False
user.save()
# Maybe redirect here
else:
messages.info(request, 'invalid registration details')
return render(
request, "users/register.html",
{"form": form}
)
这样,您就可以遍历模板中的错误。
<form method="post" action="">
{% csrf_token %}
{% if form.non_field_errors %}
{% for error in form.non_field_errors %}
{{ error }}
{% endfor %}
{% endif %}
{% for hidden in form.hidden_fields %}
{{ hidden }}
{% endfor %}
{% for field in form %}
{{ field }}
{{ field.errors.as_ul }}
{% endfor %}
<button class="btn btn-primary" type="submit">Submit</button>
</form>
像这样的更通用的模板也将对您有所帮助,因为您可以将它重用于任何表单,而不是像在您的示例中那样指定特定的表单和字段名称。
我要指出的另一件事是,您的观点有很多复杂性,例如对请求方法的大量检查。还有3种不同的形式。如果您在一个页面中有不同的表单,您可以命名提交按钮,以便您可以检查正在提交的表单。我在这里有一个答案来展示如何处理多个表单。
您user.email
没有检查用户是否经过身份验证或检查电子邮件是否存在,所以那里也有一个错误等待发生。
因此,为了简化您的视图,您可以执行以下操作(在命名表单按钮之后);
def home(request):
user = request.user
# for rendering texts
text_form = TextForm()
signin_form = SigninForm()
signup_form = SignupForm()
if request.method == "POST":
if 'text_form' in request.POST:
text_form = TextForm(request.POST)
if text_form.is_valid() and request.user.is_authenticated:
obj = text_form.save(commit=False)
author = User.objects.filter(email=user.email).first()
obj.author = author
text_form.save()
if 'signin_form' in request.POST:
signin_form = SigninForm(request.POST)
if signin_form.is_valid():
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user:
login(request, user)
elif user is None:
messages.error(request, 'ُEmail or password is incorrect')
if 'signup_form' in request.POST:
signup_form = SignupForm(request.POST)
if signup_form.is_valid():
User = signup_form.save()
full_name = signup_form.cleaned_data.get('full_name')
email = signup_form.cleaned_data.get('email')
raw_password = signup_form.cleaned_data.get('password1')
account = authenticate(email=email, password=raw_password)
login(request, account)
texts = Text.objects.all().order_by('-id')
context = {
'signin_form': signin_form,
'signup_form': signup_form,
'text_form': text_form,
'texts': texts
}
return render(request, 'main/home.html', context)
推荐阅读
- reactjs - 使用反应钩子
- webpack - webpack-cli 和 webpack-command 一起使用
- javascript - 反应组件渲染两次?
- python - 将 for 循环从 MATLAB 转换为 Python
- javascript - 如何处理这个 JSON 响应?(JS)
- python - Python 中的 Google Cloud 授权 HTTP 请求
- python - 有没有办法使用 python 将 mp3/音频文件输入到麦克风输入?
- python - Python 线程 - 程序在执行后立即结束
- c++ - 从 C++ Windows 编译 C
- javascript - 如何在正则表达式中匹配所有 MyCode,包括嵌套标签?