简体   繁体   English

Django表单验证未重定向到正确的URL

[英]Django form validation not redirecting to the correct url

I'm using Django 1.9.8 and having some trouble validating a form for registering users. 我正在使用Django 1.9.8,在验证用于注册用户的表单时遇到了一些麻烦。 If there are validation errors, the redirect back to the form is to the incorrect url. 如果存在验证错误,则重定向回表单的是错误的URL。 The registration url is localhost:8000/register . 注册网址是localhost:8000/register When errors are found (I think that's what's happening, anyway), the page is redirected to localhost:8000/register/register . 发现错误时(无论如何我都认为是这种情况),该页面将重定向到localhost:8000/register/register What am I doing incorrectly that is causing the redirect to add an additional register argument to the url? 我做错了什么导致重定向将额外的register参数添加到url?

#authorization/views.py
class RegisterViewSet(viewsets.ViewSet):

    #GET requests
    def register(self,request):
        return render(request, 'authorization/register.html', {'form': RegisterForm})

    #POST requests
    def create(self,request):
        form = RegisterForm(request.POST)
        if form.is_valid():
            username = request.POST['username']
            email = request.POST['email']
            password = request.POST['password']
            user = User.objects.create_user(username,email,password)
            user.save()
            return HttpResponseRedirect('/users') #show list of users after saving
        else:
            #return to the form for the user to fix errors & continue registering
            return render(request, 'authorization/register.html', {'form': RegisterForm}) 

Here's the RegisterForm content 这是RegisterForm的内容

#authorization/forms.py
class RegisterForm(AuthenticationForm):
    username = forms.CharField(label="Username", max_length=30,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'username'}))
    email = forms.CharField(label="Email", max_length=30,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'email'}))
    password = forms.CharField(label="Password", max_length=30,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'password', 'type' : 'password'}))
    repassword = forms.CharField(label="RePassword", max_length=30,
                               widget=forms.TextInput(attrs={'class': 'form-control', 'name': 'repassword', 'type' : 'password'}))

    def clean_password(self):
        password1 = self.cleaned_data.get('password')
        password2 = self.cleaned_data.get('repassword')
        if password1 and password1 != password2:
            raise forms.ValidationError("Passwords don't match")
        return self.cleaned_data

I'm not sure if this is relevant, but here's my urls.py 我不确定这是否相关,但这是我的urls.py

#authorization/urls.py
urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^register/', views.RegisterViewSet.as_view({'get' : 'register', 'post' : 'create'})),
]

I tested the create method prior to adding the form validation part and it was successfully saving users, so I know it at least was working up to that point. 在添加表单验证部分之前,我测试了create方法,该方法成功地保存了用户,因此我知道至少可以正常工作。

Edit - added form contents 编辑-添加表单内容

{% if form.errors %}
    {% for field in form %}
        {% for error in field.errors %}
            <div class="alert alert-error">
                <strong>{{ error|escape }}</strong>
            </div>
        {% endfor %}
    {% endfor %}
{% endif %}


<form method="post" action="register" id = "RegisterForm">
    {% csrf_token %}
    <p class="bs-component">
        <table>
            <tr>
                <td>{{ form.username.label_tag }}</td>
                <td>{{ form.username }}</td>
            </tr>
            <tr>
                <td>{{ form.email.label_tag }}</td>
                <td>{{ form.email }}</td>
            </tr>
            <tr>
                <td>{{ form.password.label_tag }}</td>
                <td>{{ form.password }}</td>
            </tr>
             <tr>
                <td>{{ form.repassword.label_tag }}</td>
                <td>{{ form.repassword }}</td>
            </tr>
        </table>
    </p>
    <p class="bs-component">
        <center>
            <input class="btn btn-success btn-sm" type="submit" value="Register" />
        </center>
    </p>
    <input type="hidden" name="next" value="{{ next }}" />
</form>

The action on your form points to a relative path, register . 表单上的action指向相对路径register If an url path does not begin with a slash, it will append it after the last slash of the current url. 如果网址路径不是以斜杠开头,则会将其附加在当前网址的最后一个斜杠之后。 Since the form is being posted to /register/register , and your url pattern matches that, that's the url you'll see when an error occurs. 由于表单已发布到/register/register ,并且您的url模式与之匹配,因此这是发生错误时将看到的url。

To fix this, you should make it an absolute url (starting with a slash) or make it empty (ie action='' ) to post to the current url. 要解决此问题,您应该将其设置为绝对网址(以斜杠开头),或者将其设为空白(即action='' )以发布到当前网址。

The most robust way to point the action to the RegisterViewSet is to use the {% url %} template tag. 将操作指向RegisterViewSet的最可靠的方法是使用{% url %}模板标记。 To use this, you need to give the url a name. 要使用此功能,您需要给url命名。 It is probably a good idea to add a $ to the pattern as well, so it only matches if /register/ is the complete url, and not if it's just the start of the url: $也添加到模式中可能是一个好主意,因此仅当/register/是完整的url时才匹配,而不是仅在url的开头时才匹配:

# authorization/urls.py
urlpatterns = [
    url(r'^$', views.home, name='home'),
    url(r'^register/$', views.RegisterViewSet.as_view({'get' : 'register', 'post' : 'create'}), name='register'),
]

# authorization/register.html
<form method="post" action="{% url 'register' %}" id="RegisterForm">
...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM