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.


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.


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


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


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

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


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.

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")
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.