Comment utiliser les vues de réinitialisation / modification de mot de passe intégrées avec mes propres modèles

92

Par exemple, je peux pointer url '^/accounts/password/reset/$'vers django.contrib.auth.views.password_resetavec mon nom de fichier de modèle dans le contexte, mais je pense que je dois envoyer plus de détails sur le contexte.

J'ai besoin de savoir exactement quel contexte ajouter pour chacune des vues de réinitialisation et de modification de mot de passe.

Tom Viner
la source
1
Étant donné le titre de cette question, je ne pense pas que ce contextsoit la bonne chose que vous recherchez!
jb.
2
Juste pour confirmer, par "contexte", je voulais dire le dictionnaire de données supplémentaires qui est le 3ème argument d'une ligne URL. aka données supplémentaires ou kwargs . Désolé pour la confusion, veuillez modifier la question, quiconque le peut.
Tom Viner

Réponses:

100

Si vous regardez les sources de django.contrib.auth.views.password_reset, vous verrez qu'il utilise RequestContext. Le résultat est que vous pouvez utiliser des processeurs de contexte pour modifier le contexte, ce qui peut vous permettre d'injecter les informations dont vous avez besoin.

La liste b a une bonne introduction aux processeurs de contexte .

Edit (il semble que je ne sache pas quelle était la question réelle):

Vous remarquerez que password_resetprend un paramètre nommé appelé 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):

Vérifier password_reset pour plus d'informations.

... ainsi, avec un urls.py comme:

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 sera appelé pour les URL correspondant '/accounts/password/reset' à l'argument mot-clé template_name = 'my_templates/password_reset.html'.

Sinon, vous n'avez pas besoin de fournir de contexte car la password_resetvue prend soin d'elle-même. Si vous voulez voir le contexte dont vous disposez, vous pouvez déclencher une TemplateSyntaxerreur et parcourir la trace de la pile pour trouver le cadre avec une variable locale nommée context. Si vous souhaitez modifier le contexte, ce que j'ai dit ci-dessus à propos des processeurs de contexte est probablement la voie à suivre.

En résumé: que devez-vous faire pour utiliser votre propre modèle? Fournissez un template_nameargument de mot - clé à la vue lorsqu'elle est appelée. Vous pouvez fournir des arguments de mot-clé aux vues en incluant un dictionnaire comme troisième membre d'un tuple de modèle d'URL.

Aaron Maenpaa
la source
Je pense que la question concerne l'utilisation de différents modèles avec des vues intégrées - les processeurs de contexte ne sont pas pris en compte!
jb.
6
une idée, comment laisser en registration/password_reset_email.htmlfait contenir des éléments html comme: <div>, <a>parce que ce texte envoie uniquement
mabdrabo
@mabdrabo - consultez cet article sur la façon de faire fonctionner HTML.
gregoltsov
26

Je recommande vivement cet article.

Je viens de le brancher et ça a marché

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

Alex Stewart
la source
2
excellent lien, merci. pour ceux qui suivent le lien - django-registration inclut désormais les vues d'authentification par défaut ... donc tout ce que vous avez à faire est de créer les modèles détaillés dans le lien ci-dessus. aussi - utilisez django-crispy-forms si vous voulez éviter tout le travail manuel de formulaire html qu'il a fait aussi.
dougvk
Il y a du code Django hérité que je dois gérer au travail, mais je ne sais presque rien du framework. Ce mec m'a sauvé le cul! Grand tutoriel
Matt Vukas
Merci pour le lien! Je pense que cela devrait être la réponse acceptée car, comme vous l'avez dit, branchez-la et cela a fonctionné.
ihatecache
10

Il vous suffit d'encapsuler les fonctions existantes et de transmettre le modèle que vous souhaitez. Par exemple:

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)

Pour voir cela, jetez un œil à la déclinaison des fonctions des vues intégrées:

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

jb.
la source
2
Pas la manière la plus simple de faire ça. Vous pouvez passer un dictionnaire comme troisième partie d'un tuple de modèles d'URL ou, si vous sentez que vous devez vraiment encapsuler la fonction, vous pouvez utiliser: password_reset = functools.partial (password, template_name = "path / to / my / template" )
Aaron Maenpaa
7

Vous pouvez faire ce qui suit:

  1. ajouter à vos urlpatterns (r '^ / accounts / password / reset / $', password_reset)
  2. mettez votre modèle dans '/templates/registration/password_reset_form.html'
  3. faire passer votre application avant 'django.contrib.auth' dans INSTALLED_APPS

Explication:

Lorsque les modèles sont chargés, ils sont recherchés dans votre variable INSTALLED_APPS dans settings.py. L'ordre est dicté par le rang de la définition dans INSTALLED_APPS, donc comme votre application est antérieure à 'django.contrib.auth', votre modèle a été chargé (référence: https://docs.djangoproject.com/en/dev/ref/templates/api /#django.template.loaders.app_directories.Loader ).

Motivation de l'approche:

  1. Je veux être plus sec et ne pas répéter pour aucune vue (définie par django) le nom du modèle (ils sont déjà définis dans django)
  2. Je veux une plus petite url.py
Lodato L
la source
2

Une autre solution, peut-être plus simple, consiste à ajouter votre répertoire de modèles de remplacement à l'entrée DIRS du paramètre TEMPLATES dans settings.py. (Je pense que ce paramètre est nouveau dans Django 1.8. Il peut avoir été appelé TEMPLATE_DIRS dans les versions précédentes de Django.)

Ainsi:

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

Ensuite, placez vos fichiers de modèle de remplacement sous my_app/templates. Ainsi, le modèle de réinitialisation du mot de passe remplacé seraitmy_app/templates/registration/password_reset_form.html

nmgeek
la source
1

La documentation dit qu'il n'y a qu'une seule variable de contexte,form .

Si vous rencontrez des problèmes de connexion (ce qui est courant), la documentation indique qu'il existe trois variables de contexte:

  • form: Un objet Form représentant le formulaire de connexion. Consultez la documentation des formulaires pour en savoir plus sur les objets Form.
  • next: URL vers laquelle rediriger après une connexion réussie. Cela peut également contenir une chaîne de requête.
  • site_name: Le nom du site actuel, selon le paramètre SITE_ID.
S.Lott
la source
2
La documentation indique qu'il existe un "argument optionnel" appelé "nom_modèle" qui semble plus pertinent.
jb.
L'argument facultatif est un argument de la fonction, pas du contexte fourni au formulaire.
S.Lott
Mmm- Je pense que la question est déroutante en ce qu'elle parle de «contexte» alors qu'en réalité, tout ce qui est pertinent pour résoudre ce problème, ce sont les arguments de l' password_resetopinion.
jb.
1

J'utilisais ces deux lignes dans l'url et le modèle de l'administrateur ce que je changeais selon mes besoins

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
la source