Bagaimana cara menggunakan tampilan reset / ubah kata sandi bawaan dengan templat saya sendiri

93

Misalnya saya dapat menunjukkan url '^/accounts/password/reset/$'ke django.contrib.auth.views.password_resetdengan nama file template saya dalam konteks tetapi saya pikir perlu mengirim lebih banyak detail konteks.

Saya perlu tahu persis konteks apa yang harus ditambahkan untuk setiap pengaturan ulang kata sandi dan mengubah tampilan.

Tom Viner
sumber
1
Mengingat judul pertanyaan ini menurut saya bukanlah contexthal yang benar yang Anda cari!
jb.
2
Sekadar konfirmasi, dengan "konteks" yang saya maksud adalah kamus data tambahan yang merupakan argumen ke-3 ke baris url. alias data ekstra atau kwarg . Maaf untuk kebingungan, silahkan edit pertanyaannya, siapapun yang bisa.
Tom Viner

Jawaban:

100

Jika Anda melihat sumber untuk django.contrib.auth.views.password_reset Anda akan melihat bahwa itu digunakan RequestContext. Hasilnya adalah, Anda dapat menggunakan Prosesor Konteks untuk mengubah konteks yang memungkinkan Anda memasukkan informasi yang Anda butuhkan.

B-list memiliki pengantar yang baik untuk pengolah konteks .

Sunting (Saya sepertinya bingung tentang apa pertanyaan sebenarnya):

Anda akan melihat bahwa password_resetmengambil parameter bernama yang disebut 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):

Periksa password_reset untuk informasi lebih lanjut.

... jadi, dengan urls.py seperti:

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_resetakan dipanggil untuk URL yang cocok '/accounts/password/reset'dengan argumen kata kunci template_name = 'my_templates/password_reset.html'.

Jika tidak, Anda tidak perlu memberikan konteks apa pun karena password_resettampilan tersebut berjalan dengan sendirinya. Jika Anda ingin melihat konteks apa yang Anda miliki, Anda dapat memicu TemplateSyntaxkesalahan dan melihat jejak tumpukan menemukan bingkai dengan variabel lokal bernama context. Jika Anda ingin mengubah konteks, apa yang saya katakan di atas tentang prosesor konteks mungkin adalah cara yang tepat.

Singkatnya: apa yang perlu Anda lakukan untuk menggunakan template Anda sendiri? Berikan template_nameargumen kata kunci ke tampilan saat dipanggil. Anda dapat memberikan argumen kata kunci ke tampilan dengan memasukkan kamus sebagai anggota ketiga tupel pola URL.

Aaron Maenpaa
sumber
Saya percaya pertanyaannya adalah tentang menggunakan templat berbeda dengan tampilan bawaan - Pemroses konteks tidak menjadi faktor di dalamnya!
jb.
6
ide, bagaimana agar registration/password_reset_email.htmlbenar-benar mengandung unsur html seperti: <div>, <a>karena ini mengirimkan teks saja
mabdrabo
@mabdrabo - lihat artikel ini tentang cara membuat HTML berfungsi.
gregoltsov
26

Sangat merekomendasikan artikel ini.

Saya baru saja mencolokkannya dan berhasil

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

Alex Stewart
sumber
2
tautan bagus, terima kasih. bagi mereka yang mengikuti tautan - django-Registration sekarang menyertakan tampilan autentikasi default ... jadi yang harus Anda lakukan adalah membuat templat yang dirinci pada tautan di atas. juga - gunakan django-crispy-forms jika Anda ingin menghindari semua pekerjaan manual formulir html yang dia lakukan juga.
dougvk
Ada beberapa kode Django warisan yang harus saya kelola di tempat kerja, tetapi saya hampir tidak tahu apa-apa tentang kerangka kerjanya. Orang itu menyelamatkan pantatku! Tutorial yang bagus
Matt Vukas
Terima kasih untuk tautannya! Saya pikir ini harus menjadi jawaban yang diterima karena seperti yang Anda katakan, menghubungkannya dan berhasil.
ihatecache
10

Anda hanya perlu membungkus fungsi yang ada dan meneruskan template yang Anda inginkan. Sebagai contoh:

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)

Untuk melihat ini, lihat saja deklarasi fungsi dari tampilan bawaan:

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

jb.
sumber
2
Bukan cara termudah untuk melakukan itu. Anda dapat memasukkan kamus sebagai bagian ketiga dari tuple pola URL atau, jika Anda merasa benar-benar harus menggabungkan fungsi tersebut, Anda dapat menggunakan: password_reset = functools.pihak (password, template_name = "path / to / my / template" )
Aaron Maenpaa
7

Anda dapat melakukan hal berikut:

  1. tambahkan ke pola url Anda (r '^ / accounts / password / reset / $', password_reset)
  2. letakkan template Anda di '/templates/registration/password_reset_form.html'
  3. buat aplikasi Anda muncul sebelum 'django.contrib.auth' di INSTALLED_APPS

Penjelasan:

Ketika templat dimuat, mereka dicari di variabel INSTALLED_APPS Anda di settings.py. Urutan ditentukan oleh peringkat definisi di INSTALLED_APPS, jadi karena aplikasi Anda datang sebelum 'django.contrib.auth', template Anda dimuat (referensi: https://docs.djangoproject.com/en/dev/ref/templates/api /#django.template.loaders.app_directories.Loader ).

Motivasi pendekatan:

  1. Saya ingin lebih kering dan tidak mengulangi untuk tampilan manapun (ditentukan oleh django) nama templatnya (mereka sudah ditentukan dalam django)
  2. Saya ingin url.py terkecil
Lodato L
sumber
2

Solusi lain, mungkin lebih sederhana, adalah menambahkan direktori template override Anda ke entri DIRS dari pengaturan TEMPLATES di settings.py. (Saya pikir pengaturan ini baru di Django 1.8. Ini mungkin telah disebut TEMPLATE_DIRS di versi Django sebelumnya.)

Seperti:

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

Kemudian taruh file template pengganti Anda di bawah my_app/templates. Jadi, template penyetelan ulang sandi yang akan diganti adalahmy_app/templates/registration/password_reset_form.html

nmgeek
sumber
1

The dokumentasi mengatakan bahwa ada hanya satu variabel konteks, form.

Jika Anda mengalami masalah dengan login (yang umum), dokumentasinya mengatakan ada tiga variabel konteks:

  • form: Objek Formulir yang mewakili formulir login. Lihat dokumentasi formulir untuk mengetahui selengkapnya tentang objek Formulir.
  • next: URL tujuan pengalihan setelah berhasil masuk. Ini mungkin berisi string kueri juga.
  • site_name: Nama Situs saat ini, menurut setelan SITE_ID.
S. Lott
sumber
2
Dokumentasi mengatakan ada "argumen opsional" yang disebut "template_name" yang tampaknya lebih relevan.
jb.
Argumen opsional adalah argumen untuk fungsi, bukan konteks yang diberikan ke formulir.
S. Lott
Mmm- Saya pikir pertanyaannya membingungkan karena berbicara tentang 'konteks' padahal semua yang relevan untuk menyelesaikan ini adalah argumen dari password_resetpandangan tersebut.
jb.
1

Saya menggunakan dua baris ini di url dan template dari admin apa yang saya ubah sesuai kebutuhan saya

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
sumber