我是Django的新手,目前正在尝试为我的应用程序创建用户注册表单。有谁知道为什么 form.is_valid()返回False?
forms.py
class RegistrationForm(forms.ModelForm):
username = forms.CharField(widget=forms.TextInput)
password = forms.CharField(widget=forms.PasswordInput)
email = forms.CharField(widget=forms.EmailInput)
class Meta:
model = User
fields = ['username', 'password', 'email']
views.py
def registration(request):
if request.method == 'POST':
form = RegistrationForm(request.POST)
if form.is_valid():
print "valid"
username = form.cleaned_data['username']
email = form.cleaned_data['email']
password = form.cleaned_data['password']
User.objects.create_user(username=username, email=email, password=password)
user = authenticate(username=username, passsword=password)
if user is not None:
login(request, user)
return redirect('/admin')
else:
# return a blank form
print "invalid"
return render(request, 'registration/register.html', {'form': form})
register.html
<div class="container ">
<form method="post" action=".">
{% csrf_token %}
<h2 class="form-signin-heading">Register</h2>
<input type="text" id="inputUsername" class="form-control" placeholder="Username" required autofocus>
<input type="password" id="inputPassword" class="form-control" placeholder="Password" required>
<input type="email" id="inputEmail" class="form-control" placeholder="Email" required autofocus>
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
</form>
答案 0 :(得分:0)
您尚未将任何HTML输入元素赋予name
属性。没有它,浏览器就无法向服务器发送任何数据。
请注意,如果您使用Django本身生成字段,它们不仅会包含名称,还会在重新显示无效表单时填充。
答案 1 :(得分:0)
我看到您在视图中定义了表单,但您没有在模板 (register.html) 中使用它。我会做更多这样的事情:
<div class="container">
<h2 class="form-signin-heading">Register</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign Up</button>
</form>
</div>
此外,如果您没有注意到,您的“return render(...)”行位于 else 块内。虽然没有必要,但我认为将上下文定义为 dict 并在视图中使用 context=context 或您命名的任何名称将其传递是一种很好的做法。但是,对于您在这里的情况,我建议使用基于类的视图。注册用户要干净得多。
from django.views.generic import CreateView
from django.urls import reverse_lazy
class Registration(CreateView):
form_class = RegistrationForm
template_name = 'register.html'
success_url = reverse_lazy('login')
# in the urls.py, set name='login' for the login page
# signing a user up will not grant admin priveleges, that is only done through the
# creation of a super user or if you coded your model to do so (not recommended)
对于任何验证,请考虑在 forms.py 中创建一个 clean(self) 方法,如下所示:
# this will be on the same block as class Meta you defined
# ensures no other user has the username with a different case
def clean(self):
cleaned_data = super(RegistrationForm, self).clean()
username = cleaned_data.get('username')
email = cleaned_data.get('email')
# checks if username is provided and ensures the username is not already in use
if username and User.objects.filter(username__iexact=username).exists():
self.add_error('username', 'A user with that username already exists.')
# checks if email is provided and ensures this email is not already in use
if email and User.objects.filter(email__iexact=email).exists():
self.add_error('email', 'That email address is already in use.')
return cleaned_data
我看到您在模板中设置了一些标签,这可以在与我刚刚提供的类 Meta 和 def clean(self) 相同的块上的 forms.py 中完成:
# method to overwrite the form label names
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['username'].label = 'Username'
self.fields['email'].label = 'Email Address'
我没有测试过这个,我的内存不足,但我认为这是一个类似于你的用例的路线,它利用了你可用的 Django 资源:) 祝你好运,我希望这会有所帮助!
>P.S:由于您使用的是引导程序,因此您应该查看 django-crispy-forms。