Show message after password change?

我怕爱的太早我们不能终老 提交于 2019-12-05 10:20:48

I wouldn't recommend checking in the settings view whether a user has arrived via a password change. I think that ideally, all of the logic for password changes is contained in the same place. This makes it easier to find the logic, and doesn't require the settings view to know about the password change view (so you could easily change the logic to redirect the user somewhere else).

Your best bet is to write your own view based on PasswordChangeForm instead of using the built-in password_change view. With this approach, you can use the message framework to display a success message. (You'll also have to enable the message framework and put its markup in your views.)

For example, if you wanted to display a simple message and redirect back to your URL pattern named 'settings', you could write a view such as this one:

from django.contrib import messages
from django.contrib.auth.forms import PasswordChangeForm
from django.core.urlresolvers import reverse_lazy
from django.views.generic import FormView


class PasswordChangeView(FormView):
    template_name = 'registration/password_change_form.html'
    form_class = PasswordChangeForm
    success_url = reverse_lazy('settings')

    def get_form_kwargs(self):
        kwargs = super(PasswordChangeView, self).get_form_kwargs()
        kwargs['user'] = self.request.user
        return kwargs

    def form_valid(self, form):
        form.save()
        messages.success(self.request, "Your password has been changed.")
        return super(FormView, self).form_valid(form)

Hopefully, the password_change view will be made class-based in the future, allowing the same behavior with even less boilerplate.

You can subclass django.contrib.auth.views.PasswordChangeView to add a message using the Django messages framework when the user successfully changes their password.

In views.py:

from django.contrib import messages
from django.contrib.auth.views import PasswordChangeView
from django.urls import reverse_lazy


class CustomPasswordChangeView(PasswordChangeView):
    # Optional (default: 'registration/password_change_form.html')
    template_name = 'myapp/my_password_change_form.html'
    # Optional (default: `reverse_lazy('password_change_done')`)
    success_url = reverse_lazy('settings')

    def form_valid(self, form):
        messages.success(self.request, 'Your password has been changed.')
        return super().form_valid(form)

Then in your app's urls.py:

from django.conf.urls import url
import myapp.views as views

urlpatterns = [
    url(r'^settings/password/change/$',
        views.CustomPasswordChangeView.as_view(),
        name='password_change'),
    # ...
]

This answer improves upon the one provided by engnoid in these ways:

  • The form behaves nearly identically to the default password change mechanism.
  • Less code repetition.
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!