0

我将内置的 django 管理站点用于应用程序的管理站点,从某种意义上说,POST请求的构建与其等效的管理站点相同,并发送到相同url的 s。所以它就像应用程序管理站点只是管理站点的包装器。

我的问题是,我不知道如何重定向回url最初发布的位置。目前它重定向到更改用户管理页面。我希望它重定向回页面。

这是我的change-password-template.html

<div>
    <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">
        </div>
            <input type="hidden" name="next" value="{% url 'change_password' id=user.pk%}"> # my attempt at trying to redirect back to the original webpage
        </div>
    </form>
</div>

因此,它确实正确发布到admin/auth/user/{{user.pk}}/password/但不是重定向该页面,而是重定向到:admin/auth/user/{{user.pk}}/change/。我怎样才能做到这一点?

4

1 回答 1

1

错误的做法...

您需要覆盖user_change_password用户管理员中的方法,因为这是重定向发生的地方:

# 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,),
                    )
                )

由于这ModelAdmin是在auth应用程序中注册的,因此您需要取消注册,添加您自己的自定义UserAdmin. django 文档中有关于如何执行此操作的明确说明。完成后,只需覆盖上面的方法并编辑重定向。

然而,这将比它的价值付出更多的努力,更重要的是,这也是一个令人讨厌的黑客行为。这不是管理界面的用途。(它还会产生意想不到的副作用,即当您实际使用管理应用程序时,它现在将重定向到您现在告诉它的任何地方 - 这将是非常不寻常的行为)。

更好的解决方案...

如果您想添加一个用户可以更改密码的端点,那么自己做并不难,这将是这种情况下的最佳解决方案。

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))

您需要添加一些额外的检查(例如,确保用户具有适当的权限,确保请求是 POST 等)。

可能还是更好...

Django 实际上有一个内置视图来执行此操作,您可以对其进行子类化来自定义。

# 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())
]

您可以在此处阅读有关这些内置视图的更多信息。

于 2020-11-06T15:23:53.220 回答