Django:形式无效

时间:2017-01-06 09:31:13

标签: python django

我是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>

2 个答案:

答案 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。