相关文章推荐
千年单身的咖啡  ·  Connect a Node.js ...·  1 年前    · 
粗眉毛的电池  ·  Android - ...·  1 年前    · 
豁达的哑铃  ·  shell - Test if a ...·  1 年前    · 
长情的自行车  ·  QT:QGraphicsView ...·  1 年前    · 
乐观的红豆  ·  三分钟教会你Java ...·  1 年前    · 
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

How to redirect to another url after sending a POST request to admin:auth_user_password_change in Django?

Ask Question

I'm using the built in django admin site for the application's admin site in a sense that POST requests are built identically to its equivalent admin site, and sent to the same url s. So it's like the application admin site is just a wrapper for the admin site.

My problem is, I don't know how to redirect back to url where it was originally posted. Currently it redirects to the Change User admin page. I'd like it to redirect back to the page.

Here's my change-password-template.html :

<form action="{% url 'admin:auth_user_password_change' user.pk %}" method="post" id="change-password-form"> {% csrf_token %} # ... here goes the password fields <input type="submit" value="Change password"> <input type="hidden" name="next" value="{% url 'change_password' id=user.pk%}"> # my attempt at trying to redirect back to the original webpage </form>

So, it does correctly post to admin/auth/user/{{user.pk}}/password/ but instead of redirecting back to the that page it instead redirects to: admin/auth/user/{{user.pk}}/change/ . How can I make it do so?

The wrong way to do it...

You would need to overwrite the user_change_password method in your User admin, since that is where the redirect happens:

# contrib.auth.admin.py
    def user_change_password(self, request, id, form_url=''):
        if request.method == 'POST':
            form = self.change_password_form(user, request.POST)
            if form.is_valid():
                return HttpResponseRedirect(
                    reverse(
                        '%s:%s_%s_change' % (
                            self.admin_site.name,
                            user._meta.app_label,
                            user._meta.model_name,
                        args=(user.pk,),

Since this ModelAdmin is registered in the auth app, you will need to unregister that, add your own custom UserAdmin. There are clear instructions on how to do this in the django docs. Once you have done that simply overwrite the method above and edit the redirect.

This would be much more effort than it's worth however, and more importantly it would also be a nasty hack. It's not what the admin interface is intended for. (It would also have the unintended side-effect that when you actually do use the admin app, it will now redirect to wherever you now have told it to - this would be very unusual behaviour).

A better solution...

If you want to add an end-point where a user can change their password it's not difficult to do it yourself, and that would be the best solution in this case.

from django.contrib.auth.models import User
from django.http import HttpResponseRedirect
from django.urls import reverse
def change_password(request, user_id):
    new_password = request.POST["password"]
    user = User.objects.get(id=user_id)
    user.set_password(new_password)
    user.save()
    return HttpResponseRedirect(reverse('your_url_here))

You'll need to add some additional checks (e.g. make sure the user has the appropriate permissions, make sure the request is a POST etc.).

Probably better still...

Django actually has a built in view for doing this, that you can subclass to customise.

# views.py
from django.contrib.auth.views import PasswordChangeView
class MyPasswordChangeView(PasswordChangeView):
    success_url = reverse("url_to_redirect_to")
# urls.py
urlpatters = [
    path('change_password', MyPasswordChangeViews.as_view())

You can read more about these built in views here.

Ahhh. I tried to go "All HTML" route here as I saw an example wherein a user can change his own password in a similar structure as I said, and posted it to {% url 'password_change' %} but the equivalent function in view only contains return redirect('/profile/?status=error') so I figured he must have used something pre-built to pull it off? – mashedpotatoes Nov 6, 2020 at 15:50 @mashedpotatoes ah, there is actually a built in view that you can use. I had forgotten about that. I've added another way of doing what you want which uses django's built in PasswordChangeView. If you're happy with this solution please mark the answer as correct :) – tim-mccurrach Nov 6, 2020 at 16:10 I'm doing this as an admin changing the user's password, not the user himself. My understanding of PasswordChangeView is it's for the user changing his own password. Is there a way to use this view as an admin? – mashedpotatoes Nov 6, 2020 at 16:54 If you want to restrict a view to just admin users, you can use the user_passes_test decorator. Or for class based views such as this one, you can use the UserPassesTestMixin. You can read about it here docs.djangoproject.com/en/3.1/topics/auth/default/… – tim-mccurrach Nov 6, 2020 at 18:03 But then how to indicate the id of the User whose password is going to be changed in PasswordChangeView? I expect something like in your 2nd solution where you need the user_id to do so.. – mashedpotatoes Nov 6, 2020 at 18:10

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.