当我尝试提交一个空表单时,表单没有显示错误消息,但是当我在views.py
中循环字段错误时,我可以看到错误。我该如何克服这个问题?template
(已更新):
{% block formcontent %}
{{form.non_field_errors}}
<div class="row">
<div class="col">
{{form.username.label_tag}} {{form.username}} {{form.username.errors|striptags}}
</div>
</div><br>
<div class="row">
<div class="col">
{{form.first_name.label_tag}} {{form.first_name}} {{form.first_name.errors|striptags}}
</div>
<div class="col">
{{form.last_name.label_tag}} {{form.last_name}} {{form.last_name.errors|striptags}}
</div>
</div><br>
<div class="row">
<div class="col">
{{form.email.label_tag}} {{form.email}} {{form.email.errors|striptags}}
</div>
</div><br>
<div class="row">
<div class="col">
{{form.location.label_tag}} {{form.location}} {{form.location.errors|striptags}}
</div>
<div class="col">
{{form.designation.label_tag}} {{form.designation}} {{form.designation.errors|striptags}}
</div>
</div><br>
<div class="row">
<div class="col">
{{form.password1.label_tag}} {{form.password1}} {{form.password1.errors|striptags}}
</div>
<div class="col">
{{form.password2.label_tag}} {{form.password2}} {{form.password2.errors|striptags}}
</div>
</div><br>
{% endblock formcontent %}
编辑1:(更新)
class MyRegistrationForm(UserCreationForm):
password1=forms.CharField(label='Password', widget=forms.PasswordInput(attrs={'class':'form-control'}))
password2=forms.CharField(label='Confirm Password', widget=forms.PasswordInput(attrs={'class':'form-control'}))
class Meta:
model=MyRegistration
fields=['username', 'first_name', 'last_name', 'email', 'location', 'designation']
widgets={
'username':forms.TextInput(attrs={'class':'form-control'}),
'first_name':forms.TextInput(attrs={'class':'form-control'}),
'last_name':forms.TextInput(attrs={'class':'form-control'}),
'email':forms.EmailInput(attrs={'class':'form-control'}),
'location':forms.Select(attrs={'class':'form-select'}),
'designation':forms.TextInput(attrs={'class':'form-control'}),
}
def clean_username(self):
username = self.cleaned_data.get('username')
if not username:
raise ValidationError('Username is required!')
else:
try:
MyRegistration.objects.get(username=username)
raise ValidationError('This username already exists!', code='username_exists')
except MyRegistration.DoesNotExist:
pass
return username
def clean_email(self):
email=self.cleaned_data.get('email')
if not email:
raise ValidationError('Email is required!')
else:
try:
MyRegistration.objects.get(email=email)
raise ValidationError('This email already exists!', code='email_exists')
except MyRegistration.DoesNotExist:
pass
return email
def clean_first_name(self):
first_name=self.cleaned_data.get('first_name')
if not first_name:
raise ValidationError('First-name is required!')
return first_name
def clean_last_name(self):
last_name=self.cleaned_data.get('last_name')
if not last_name:
raise ValidationError('Last-name is required!')
return last_name
def clean_location(self):
location=self.cleaned_data.get('location')
if not location:
raise ValidationError('Location is required!')
return location
def clean_designation(self):
designation=self.cleaned_data.get('designation')
if not designation:
raise ValidationError('Designation is required!')
return designation
我真的不知道我在模板中的代码有什么问题。我已经检查过了,Django文档建议用同样的方法来处理表单没有循环的场景。
编辑二:
models.py:
class MyRegistration(AbstractBaseUser, PermissionsMixin):
location_list=[
('Solapur', 'Solapur'),
('Dhule', 'Dhule'),
('Other', 'Other'),
]
username=models.CharField(max_length=10, unique=True)
email=models.EmailField(unique=True)
first_name=models.CharField(max_length=150)
last_name=models.CharField(max_length=150)
location=models.CharField(max_length=10, choices=location_list, default=None)
designation=models.CharField(max_length=70)
is_active=models.BooleanField()
is_staff=models.BooleanField(default=False)
start_date=models.DateTimeField(default=timezone.now)
last_login=models.DateTimeField(null=True)
USERNAME_FIELD='username'
REQUIRED_FIELDS=['email', 'first_name', 'last_name', 'location', 'designation']
objects=FirstManager()
def __str__(self):
return self.first_name
views.py:(已更新)
def signup(request):
print('1')
if request.user.is_authenticated:
print('2')
if request.method=='POST':
print('3')
if request.POST.get('password1')==request.POST.get('password2'):
print('4')
fm=MyRegistrationForm(request.POST)
for field in fm:
print("Field Error:", field.name, field.errors)
if fm.is_valid():
print('6')
fm.save()
messages.success(request, 'Registered successfully!!')
fm=MyRegistrationForm()
print('7')
cur_user=request.user
return render(request, 'account/signup.html', {'form':fm, 'cur_user':cur_user})
else:
fm=MyRegistrationForm()
cur_user=request.user
return render(request, 'account/signup.html', {'form':fm, 'cur_user':cur_user})
else:
return HttpResponseRedirect('/')
1条答案
按热度按时间hmae6n7t1#
在
clean
方法中引发ValidationError
时,这些错误将添加到窗体的non_field_errors
属性中,这就是为什么在特定字段上使用form.email.errors
和其他errors
属性时不会呈现任何内容的原因。您应该在呈现窗体之前呈现
form.non_field_errors
,这样您也可以看到这些错误。然而,为了解决您的问题,我宁愿选择将每个字段的验证拆分为特定的方法
clean_<field_name>
。例如,对于用户名字段:对于其他字段也是如此。这样做应该可以修复代码,但这里有一些其他的建议:
ValidationErrors
取整时使用代码。例如:raise ValidationError('This username already exists', code='username_exists')
**EDIT #1:**使用
instance
从提交的表单中获取值是错误的。由于此表单专门用于创建目的,因为注册是创建新用户,因此instance
将始终为空。instance
仅在更新模型示例时填充数据。您应该将
instance
的使用替换为从self.cleaned_data
dict获取表单数据。例如:**EDIT #2:**作者添加视图代码后。
问题可能出在您的视图代码中。另外,没有必要比较
password1
和password2
,因为UserCreationForm
已经为您的做了这件事。核心问题是,如果表单无效,您需要重新呈现相同的表单,而不是创建另一个示例。
其他一些建议:
@login_required
装饰器可能更适合。render
,只有在处理GET方法或需要重新呈现表单以显示验证错误时才使用。