Как использовать встроенные просмотры сброса / изменения пароля с моими собственными шаблонами

93

Например , я могу указать url '^/accounts/password/reset/$'на django.contrib.auth.views.password_resetс моим шаблоном файлом в контексте , но я думаю , что нужно послать больше информации контекста.

Мне нужно точно знать, какой контекст добавить для каждого из представлений сброса и изменения пароля.

Том Винер
источник
1
Учитывая название этого вопроса, я не думаю, что contextэто то, что вы ищете!
jb.
2
Просто чтобы подтвердить, что под «контекстом» я имел в виду словарь дополнительных данных, который является третьим аргументом строки url. ака дополнительные данные или kwargs . Извините за недоразумение, пожалуйста, отредактируйте вопрос, кто может.
Tom Viner

Ответы:

100

Если вы посмотрите на исходные коды django.contrib.auth.views.password_reset, вы увидите, что он использует RequestContext. В результате вы можете использовать контекстные процессоры для изменения контекста, что может позволить вам вводить необходимую информацию.

B-список дает хорошее введение в процессоры контекста .

Изменить (кажется, я был смущен тем, что был на самом деле вопрос):

Вы заметите, что он 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'}),
     ...
)

django.contrib.auth.views.password_resetбудет вызываться для URL-адресов, совпадающих '/accounts/password/reset'с аргументом ключевого слова template_name = 'my_templates/password_reset.html'.

В противном случае вам не нужно предоставлять какой-либо контекст, поскольку password_resetпредставление само о себе позаботится. Если вы хотите узнать, какой контекст у вас есть, вы можете вызвать TemplateSyntaxошибку и просмотреть трассировку стека, чтобы найти фрейм с локальной переменной с именем context. Если вы хотите изменить контекст, то, вероятно, вам подойдет то, что я сказал выше о процессорах контекста.

Итак: что вам нужно сделать, чтобы использовать собственный шаблон? При вызове представления template_nameукажите аргумент ключевого слова. Вы можете предоставить аргументы ключевого слова для представлений, включив словарь в качестве третьего члена кортежа шаблона URL.

Аарон Маенпаа
источник
Я считаю, что вопрос заключается в использовании разных шаблонов со встроенными представлениями - контекстные процессоры здесь не учитываются!
jb.
6
любая идея, как дать на registration/password_reset_email.htmlсамом деле содержат HTML элементы , такие как: <div>, <a>потому что это посылает только текст
mabdrabo
@mabdrabo - прочтите эту статью о том, как заставить работать HTML.
gregoltsov 05
26

Настоятельно рекомендую эту статью.

Я просто подключил его, и он заработал

http://garmoncheg.blogspot.com.au/2012/07/django-resetting-passwords-with.html

Алекс Стюарт
источник
2
отличная ссылка, спасибо. для тех, кто переходит по ссылке - django-registration теперь включает представления аутентификации по умолчанию ... поэтому все, что вам нужно сделать, это создать шаблоны, подробно описанные в приведенной выше ссылке. также - используйте django-crispy-forms, если вы хотите избежать всей ручной работы с HTML-формами, которую он делал.
dougvk
Есть некоторый унаследованный код Django, которым я должен управлять на работе, но я почти ничего не знаю о структуре. Этот парень спас мою задницу! Отличный учебник
Мэтт Вукас
Спасибо за ссылку! Я думаю, что это должен быть принятый ответ, поскольку, как вы сказали, подключил его, и он сработал.
ihatecache
10

Вам просто нужно обернуть существующие функции и передать нужный шаблон. Например:

from django.contrib.auth.views import password_reset

def my_password_reset(request, template_name='path/to/my/template'):
    return password_reset(request, template_name)

Чтобы убедиться в этом, просто взгляните на объявление функции встроенных представлений:

http://code.djangoproject.com/browser/django/trunk/django/contrib/auth/views.py#L74

jb.
источник
2
Не самый простой способ сделать это. Вы можете передать словарь как третью часть кортежа шаблонов URL или, если вы действительно чувствуете, что вам действительно нужно обернуть функцию, вы можете использовать: password_reset = functools.partial (password, template_name = "path / to / my / template" )
Аарон Маенпаа
7

Вы можете сделать следующее:

  1. добавьте в свои шаблоны URL (r '^ / accounts / password / reset / $', password_reset)
  2. поместите свой шаблон в '/templates/registration/password_reset_form.html'
  3. сделайте ваше приложение раньше 'django.contrib.auth' в INSTALLED_APPS

Пояснение:

Когда шаблоны загружены, они ищутся в вашей переменной INSTALLED_APPS в settings.py. Порядок определяется рангом определения в 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
Lodato L
источник
2

Другое, возможно, более простое решение - добавить каталог переопределенных шаблонов в запись DIRS параметра TEMPLATES в settings.py. (Я думаю, что этот параметр является новым в 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

NMgeek
источник
1

В документации говорится, что существует только одна контекстная переменная 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")
Azd325
источник