Jak używać wbudowanych widoków resetowania / zmiany hasła z własnymi szablonami

93

Na przykład mogę wskazać url '^/accounts/password/reset/$'do django.contrib.auth.views.password_resetz nazwą pliku szablonu w kontekście, ale myślę, że muszę wysłać więcej szczegółów kontekstu.

Muszę dokładnie wiedzieć, jaki kontekst dodać dla każdego resetowania hasła i zmiany widoków.

Tom Viner
źródło
1
Biorąc pod uwagę tytuł tego pytania, uważam, że nie contextjest to właściwe rozwiązanie!
jb.
2
Dla potwierdzenia, przez „kontekst” miałem na myśli słownik dodatkowych danych, który jest trzecim argumentem linii url. aka dodatkowe dane lub kwargs . Przepraszamy za zamieszanie, edytuj pytanie, każdy, kto może.
Tom Viner

Odpowiedzi:

100

Jeśli spojrzysz na źródła dla django.contrib.auth.views.password_reset , zobaczysz, że używa RequestContext. W rezultacie możesz użyć procesorów kontekstu, aby zmodyfikować kontekst, co może pozwolić na wstrzyknięcie potrzebnych informacji.

Lista b ma dobre wprowadzenie do procesorów kontekstu .

Edytuj (wydaje mi się, że byłem zdezorientowany, jakie było rzeczywiste pytanie):

Zauważysz, że password_resetprzyjmuje nazwany parametr o nazwie 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):

Sprawdź password_reset, aby uzyskać więcej informacji.

... a więc z urls.py jak:

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_resetbędzie wywoływana w przypadku adresów URL pasujących '/accounts/password/reset'do argumentu słowa kluczowego template_name = 'my_templates/password_reset.html'.

W przeciwnym razie nie musisz podawać żadnego kontekstu, ponieważ password_resetwidok sam się o siebie troszczy. Jeśli chcesz zobaczyć, jaki kontekst masz dostępny, możesz wywołać TemplateSyntaxbłąd i przejrzeć ślad stosu, aby znaleźć ramkę z lokalną zmienną o nazwie context. Jeśli chcesz zmodyfikować kontekst, to prawdopodobnie najlepsze jest to, co powiedziałem powyżej o procesorach kontekstu.

Podsumowując: co musisz zrobić, aby użyć własnego szablonu? Podaj template_nameargument słowa kluczowego do widoku, gdy jest on wywoływany. Możesz dostarczać argumenty słów kluczowych do widoków, dołączając słownik jako trzeci element członkowski krotki wzorca adresu URL.

Aaron Maenpaa
źródło
Uważam, że chodzi o używanie różnych szablonów z wbudowanymi widokami - procesory kontekstu nie uwzględniają tego!
jb.
6
Każdy pomysł, jak pozwolić registration/password_reset_email.htmlfaktycznie zawierać elementy HTML, takich jak: <div>, <a>bo to wysyła tylko tekst
mabdrabo
@mabdrabo - przeczytaj ten artykuł o tym, jak uruchomić HTML.
gregoltsov
26

Gorąco polecam ten artykuł.

Po prostu go podłączyłem i zadziałało

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

Alex Stewart
źródło
2
świetny link, dzięki. dla tych, którzy podążają za linkiem - rejestracja django zawiera teraz domyślne widoki autoryzacji ... więc wszystko, co musisz zrobić, to stworzyć szablony wyszczególnione w powyższym linku. również - użyj django-crispy-forms, jeśli chcesz uniknąć wszystkich ręcznych form HTML, które on również wykonywał.
dougvk
Jest jakiś stary kod Django, którym muszę zarządzać w pracy, ale prawie nic nie wiem o frameworku. Ten facet uratował mi tyłek! Świetny tutorial
Matt Vukas
Dzięki za link! Myślę, że to powinna być akceptowana odpowiedź, ponieważ tak jak powiedziałeś, podłączyłem go i zadziałało.
ihatecache
10

Wystarczy opakować istniejące funkcje i przekazać żądany szablon. Na przykład:

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)

Aby to zobaczyć, spójrz na deklarację funkcji wbudowanych widoków:

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

jb.
źródło
2
Nie jest to najprostszy sposób. Możesz przekazać słownik jako trzecią część krotki wzorców adresów URL lub, jeśli naprawdę musisz opakować funkcję, możesz użyć: hasło_reset = functools.partial (hasło, nazwa_ szablonu = "ścieżka / do / mój / szablon" )
Aaron Maenpaa
7

Możesz wykonać następujące czynności:

  1. dodaj do swoich wzorców url (r '^ / accounts / password / reset / $', password_reset)
  2. umieść swój szablon w „/templates/registration/password_reset_form.html”
  3. spraw, aby Twoja aplikacja znajdowała się przed „django.contrib.auth” w INSTALLED_APPS

Wyjaśnienie:

Kiedy szablony są ładowane, są przeszukiwane w zmiennej INSTALLED_APPS w settings.py. Kolejność jest podyktowana rangą definicji w INSTALLED_APPS, więc ponieważ Twoja aplikacja znajduje się przed 'django.contrib.auth', Twój szablon został załadowany (odnośnik: https://docs.djangoproject.com/en/dev/ref/templates/api /#django.template.loaders.app_directories.Loader ).

Motywacja podejścia:

  1. Chcę być bardziej suchy i nie powtarzam dla żadnego widoku (zdefiniowanego przez django) nazwy szablonu (są już zdefiniowane w django)
  2. Chcę mieć najmniejszy adres url.py
Lodato L
źródło
2

Innym, być może prostszym rozwiązaniem jest dodanie katalogu nadpisań szablonów do wpisu DIRS w ustawieniu TEMPLATES w settings.py. (Myślę, że to ustawienie jest nowe w Django 1.8. Mogło nazywać się TEMPLATE_DIRS w poprzednich wersjach Django).

Tak jak to:

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

Następnie umieść pliki szablonów nadpisań pod my_app/templates. Więc zastąpiony szablon resetowania hasła byłbymy_app/templates/registration/password_reset_form.html

nmgeek
źródło
1

Dokumentacja mówi, że istnieje tylko jedna zmienna kontekstowego form.

Jeśli masz problemy z logowaniem (co jest częste), dokumentacja mówi, że istnieją trzy zmienne kontekstowe:

  • form: Obiekt Form reprezentujący formularz logowania. Zobacz dokumentację formularzy, aby uzyskać więcej informacji na temat obiektów Form.
  • next: Adres URL do przekierowania po pomyślnym zalogowaniu. Może również zawierać ciąg zapytania.
  • site_name: Nazwa bieżącej witryny, zgodnie z ustawieniem SITE_ID.
S.Lott
źródło
2
Dokumentacja mówi, że istnieje „opcjonalny argument” o nazwie „nazwa_ szablonu”, który wydaje się bardziej odpowiedni.
jb.
Opcjonalny argument jest argumentem funkcji, a nie kontekstem dostarczonym do formularza.
S.Lott,
Mmm… Myślę, że pytanie jest zagmatwane, ponieważ mówi o „kontekście”, podczas gdy tak naprawdę wszystko, co jest istotne dla rozwiązania tego, to argumenty password_resetpoglądu.
jb.
1

Używałem tych dwóch linii w adresie URL i szablonie od administratora, co zmieniałem według moich potrzeb

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
źródło