如何使用内置的密码重置/更改视图与自己的模板?

97
例如,我可以将url '^/accounts/password/reset/$'指向django.contrib.auth.views.password_reset,并在上下文中添加我的模板文件名,但我认为需要发送更多上下文细节。
我需要确切地知道为每个密码重置和更改视图添加哪些上下文。

1
鉴于这个问题的标题,我认为context并不是你要找的正确答案! - jb.
2
只是确认一下,我所说的“上下文”,指的是URL行的第三个参数,即额外数据的字典。也就是额外数据或kwargs。对于造成的混淆,非常抱歉,请编辑问题的人进行修改。 - Tom Viner
7个回答

103
如果你查看django.contrib.auth.views.password_reset的源码,你会发现它使用了RequestContext。总之,你可以使用上下文处理器来修改上下文,这可能允许你注入所需的信息。 有一个关于上下文处理器的好的介绍

编辑(我似乎对实际问题感到困惑):
你会注意到password_reset接受一个名为template_name的命名参数:
def password_reset(request, is_admin_site=False, 
            template_name='registration/password_reset_form.html',
            email_template_name='registration/password_reset_email.html',
            password_reset_form=PasswordResetForm, 
            token_generator=default_token_generator,
            post_reset_redirect=None):

查看password_reset获取更多信息。

因此,使用以下urls.py:

from django.conf.urls.defaults import *
from django.contrib.auth.views import password_reset

urlpatterns = patterns('',
     (r'^/accounts/password/reset/$', password_reset, {'template_name': 'my_templates/password_reset.html'}),
     ...
)

当URL匹配'/accounts/password/reset'并且关键字参数template_name = 'my_templates/password_reset.html'被调用时,django.contrib.auth.views.password_reset将被调用。

否则,由于password_reset视图会自行处理,所以您不需要提供任何上下文。如果您想查看可用的上下文,可以触发TemplateSyntax错误,并查找带有名为context的局部变量的帧的堆栈跟踪。如果您想修改上下文,那么上面提到的上下文处理器可能是正确的方法。

总之,要如何使用自己的模板?在调用视图时提供template_name关键字参数。您可以通过在URL模式元组的第三个成员中包含一个字典来向视图提供关键字参数。


我相信这个问题是关于在内置视图中使用不同模板的,上下文处理器与此无关! - jb.
6
有什么办法让registration/password_reset_email.html实际包含HTML元素,比如<div><a>,因为目前只发送文本。 - mabdrabo
@mabdrabo - 请查看这篇文章,了解如何让HTML正常工作。 - gregoltsov

27

2
非常好的链接,谢谢。对于那些跟随链接的人 - django-registration现在包括默认的auth视图...所以你只需要创建上面链接中详细说明的模板。另外 - 如果你想避免所有手动的HTML表单工作,可以使用django-crispy-forms。 - dougvk
我在工作中需要管理一些遗留的Django代码,但我几乎不了解这个框架。那个人真是救了我!他的教程非常好。 - Matt Vukas
感谢提供链接!我认为这应该是被接受的答案,因为像你说的那样,插上它就可以工作了。 - ihatecache

10

2
这并不是最简单的方法。你可以将一个字典作为 URL 模式元组的第三个部分传递进去,或者如果你真的想要包装这个函数,你可以使用:password_reset = functools.partial(password, template_name="path/to/my/template")。 - Aaron Maenpaa

8
你可以执行以下操作:
  1. 将(r'^/accounts/password/reset/$', password_reset)添加到urlpatterns中
  2. 将模板放在'/templates/registration/password_reset_form.html'中
  3. 确保在INSTALLED_APPS中,你的应用程序排在'django.contrib.auth'的前面
解释:
当模板被加载时,它们会在settings.py文件中的INSTALLED_APPS变量中进行搜索。其顺序由其在INSTALLED_APPS中的位置决定,因此你的应用程序排在'django.contrib.auth'之前,你的模板将被加载(参考文献:https://docs.djangoproject.com/en/dev/ref/templates/api/#django.template.loaders.app_directories.Loader)。
方法说明:
  1. 我希望更简洁,而不是为每个视图(由django定义)重复模板名称(它们已经在django中定义)
  2. 我想要一个最小的url.py文件

2

另一种也许更简单的解决方案是将您的覆盖模板目录添加到settings.py中TEMPLATES设置的DIRS条目中。(我认为这个设置在Django 1.8中是新的,以前的Django版本可能被称为TEMPLATE_DIRS。)

像这样:

TEMPLATES = [
   {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        # allow overriding templates from other installed apps                                                                                                
        'DIRS': ['my_app/templates'],
        'APP_DIRS': True,
}]

将您的覆盖模板文件放在my_app/templates下。 因此,重写的密码重置模板将是my_app/templates/registration/password_reset_form.html


1

文档中提到只有一个上下文变量form

如果您在登录方面遇到问题(这很常见),文档中提到有三个上下文变量:

  • form:表示登录表单的Form对象。有关Form对象的更多信息,请参阅表单文档。
  • next:成功登录后要重定向到的URL。这也可能包含查询字符串。
  • site_name:根据SITE_ID设置,当前站点的名称。

2
文档中提到有一个名为“template_name”的“可选参数”,似乎更相关。 - jb.
可选参数是传递给函数的参数,而不是提供给表单的上下文。 - S.Lott
嗯,我认为这个问题有点混淆了,因为它谈到了“上下文”,而实际上解决这个问题只需要关注password_reset视图的参数即可。 - jb.

1
我在URL中使用了这两行代码,并使用来自管理员的模板,我对其进行了修改以满足我的需求。
url(r'^change-password/$', 'django.contrib.auth.views.password_change', {
    'template_name': 'password_change_form.html'}, name="password-change"),
url(r'^change-password-done/$', 'django.contrib.auth.views.password_change_done', {
    'template_name': 'password_change_done.html'
    }, name="password-change-done")

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接