简体   繁体   中英

Django : NoReverseMatch at when changing password using form

I'm trying to make form and method which allows users to change their password. When user type their password into two inputs than form will check if those are same and update db. However I got this error and I couldn't solve it.

error message

NoReverseMatch at /blog/password_change/blue/
Reverse for 'profile' with arguments '()' and keyword arguments '{}' not found. 1 pattern(s) tried: [u'blog/profile/(?P<username>[-\\w.]+)/$']

urls.py

url(r'^password_change/(?P<username>[-\w.]+)/$', views.password_change, name='password_change'),
url(r'^profile/(?P<username>[-\w.]+)/$', views.profile, name='profile'),

views.py

def password_change(request, username):
if request.method == 'POST':
    form = PasswordChangeForm(data=request.POST, user=request.user)

    if form.is_valid():
        form.save()
        update_session_auth_hash(request, form.user)
        return redirect(reverse('blog:profile'))
    else:
        return redirect(reverse('blog:profile'))
else:
    form = PasswordChangeForm(user=request.user)

    return HttpResponseRedirect('/blog/')

profile.html. this is the template.

 <form class="form-horizontal" role="form" action="{% url'blog:password_change' user.username %}" method="post" enctype="multipart/form-data">
{% csrf_token %}
<label for="password1">new password</label>
 <div class="row">
    <input type="password" name="password1" id="password1"/></div>
<div class="row">
<label for="password2">password check</label></div>
 <div class="row">
    <input type="password" name="password2" id="password2"/></div>
 <div class="row">  
      <button type="submit" class="button-primary">change password</button></div>

views.py

def password_change(request, username):
if request.method == 'POST':
    form = PasswordChangeForm(data=request.POST, user=request.user)

    if form.is_valid():
        form.save()
        update_session_auth_hash(request, form.user)
        return redirect(reverse('blog:profile'))
    else:
        return redirect(reverse('blog:profile'))
else:
    form = PasswordChangeForm(user=request.user)

    return HttpResponseRedirect('/blog/')

This is forms.py

 class PasswordChangeForm(forms.ModelForm):
    error_messages = {
    'password_mismatch': ("The two password fields didn't match."),
}
password1 = forms.CharField(
    label=("Password"),
    strip=False,
    widget=forms.PasswordInput,
    help_text=password_validation.password_validators_help_text_html(),
)
password2 = forms.CharField(
    label=("Password confirmation"),
    widget=forms.PasswordInput,
    strip=False,
    help_text=("Enter the same password as before, for verification."),
)

class Meta:
    model = User
    fields = ("username",)
    field_classes = {'username': UsernameField}

def __init__(self, *args, **kwargs):
    super().__init__(*args, **kwargs)
    if self._meta.model.USERNAME_FIELD in self.fields:
        self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True})

def clean_password2(self):
    password1 = self.cleaned_data.get("password1")
    password2 = self.cleaned_data.get("password2")
    if password1 and password2 and password1 != password2:
        raise forms.ValidationError(
            self.error_messages['password_mismatch'],
            code='password_mismatch',
        )
    self.instance.username = self.cleaned_data.get('username')
    password_validation.validate_password(self.cleaned_data.get('password2'), self.instance)
    return password2

def save(self, commit=True):
    user = super().save(commit=False)
    user.set_password(self.cleaned_data["password1"])
    if commit:
        user.save()
    return user     

As your error states, you need an argument for your username in profile url, which you don't provide at all.

For example:

 return redirect(reverse('blog:profile'))

should be

 return redirect(reverse('blog:profile', args=[form.user.get_username()]))

You must pass username to reverse().

username = form.user.get_username()

reverse('blog:profile', kwargs={'username':username})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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