Como utilizo as visualizações de redefinição / alteração de senha integradas com meus próprios modelos

92

Por exemplo, posso apontar o url '^/accounts/password/reset/$'para django.contrib.auth.views.password_resetcom meu nome de arquivo do modelo no contexto, mas acho que preciso enviar mais detalhes do contexto.

Preciso saber exatamente qual contexto adicionar para cada redefinição de senha e alterar visualizações.

Tom Viner
fonte
1
Dado o título desta pergunta, acho que não contexté a coisa certa que você está procurando!
jb.
2
Apenas para confirmar, por "contexto" eu quis dizer o dicionário de dados extras que é o terceiro argumento para uma linha de url. também conhecido como dados extras ou kwargs . Desculpe pela confusão, por favor edite a pergunta, quem puder.
Tom Viner

Respostas:

100

Se você der uma olhada nas fontes de django.contrib.auth.views.password_reset você verá que ele usa RequestContext. O resultado é que você pode usar Processadores de Contexto para modificar o contexto, o que pode permitir que você injete as informações de que precisa.

A lista b tem uma boa introdução aos processadores de contexto .

Editar (parece que fiquei confuso sobre qual era a questão real):

Você notará que password_resetleva um parâmetro nomeado chamado 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):

Verifique password_reset para mais informações.

... assim, com um urls.py como:

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_resetserá chamado para URLs correspondentes '/accounts/password/reset'ao argumento de palavra-chave template_name = 'my_templates/password_reset.html'.

Caso contrário, você não precisa fornecer nenhum contexto, pois a password_resetvisualização se auto-administra. Se quiser ver o contexto disponível, você pode acionar um TemplateSyntaxerro e examinar o rastreamento da pilha, localizar o quadro com uma variável local chamada context. Se você deseja modificar o contexto, então o que eu disse acima sobre processadores de contexto é provavelmente o caminho a percorrer.

Em resumo: o que você precisa fazer para usar seu próprio modelo? Fornece um template_nameargumento de palavra - chave para a exibição quando ela é chamada. Você pode fornecer argumentos de palavra-chave para visualizações incluindo um dicionário como o terceiro membro de uma tupla de padrão de URL.

Aaron Maenpaa
fonte
Acredito que a questão seja sobre o uso de modelos diferentes com visualizações integradas - os processadores de contexto não são considerados nisso!
jb.
6
qualquer idéia, como deixar registration/password_reset_email.htmlrealmente conter elementos HTML, como: <div>, <a>porque este envia apenas texto
mabdrabo
@mabdrabo - verifique este artigo sobre como fazer o HTML funcionar.
gregoltsov
26

Recomendo vivamente este artigo.

Eu apenas conectei e funcionou

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

Alex Stewart
fonte
2
ótimo link, obrigado. para aqueles que seguem o link - django-registration agora inclui as visualizações de autenticação padrão ... então tudo que você precisa fazer é criar os modelos detalhados no link acima. também - use django-crispy-forms se você quiser evitar todo o trabalho de formulário html manual que ele fez também.
dougvk
Há algum código legado do Django que preciso gerenciar no trabalho, mas quase não sei nada sobre o framework. Esse cara salvou minha bunda! Ótimo tutorial
Matt Vukas
Obrigado pelo link! Acho que essa deve ser a resposta aceita, já que como você disse, conectei e funcionou.
ihatecache de
10

Você só precisa agrupar as funções existentes e passar o modelo desejado. Por exemplo:

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)

Para ver isso, basta dar uma olhada na declaração de função das visualizações integradas:

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

jb.
fonte
2
Não é a maneira mais simples de fazer isso. Você pode passar um dicionário como uma terceira parte de uma tupla de padrões de URL ou, se sentir que realmente deve encapsular a função, pode usar: password_reset = functools.partial (password, template_name = "path / to / my / template" )
Aaron Maenpaa
7

Você pode fazer o seguinte:

  1. adicione ao seu urlpatterns (r '^ / accounts / password / reset / $', password_reset)
  2. coloque seu modelo em '/templates/registration/password_reset_form.html'
  3. faça seu aplicativo vir antes de 'django.contrib.auth' em INSTALLED_APPS

Explicação:

Quando os modelos são carregados, eles são pesquisados ​​na variável INSTALLED_APPS em settings.py. A ordem é ditada pela classificação da definição no INSTALLED_APPS, portanto, como seu aplicativo vem antes de 'django.contrib.auth', seu modelo foi carregado (referência: https://docs.djangoproject.com/en/dev/ref/templates/api /#django.template.loaders.app_directories.Loader ).

Motivação de abordagem:

  1. Quero ser mais seco e não repetir para nenhuma visão (definida pelo django) o nome do modelo (eles já estão definidos no django)
  2. Eu quero o menor url.py
Lodato L
fonte
2

Outra solução, talvez mais simples, é adicionar seu diretório de modelos de substituição à entrada DIRS da configuração TEMPLATES em settings.py. (Eu acho que essa configuração é nova no Django 1.8. Ela pode ter se chamado TEMPLATE_DIRS nas versões anteriores do Django.)

Igual a:

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

Em seguida, coloque seus arquivos de modelo de substituição em my_app/templates. Portanto, o modelo de redefinição de senha substituído seriamy_app/templates/registration/password_reset_form.html

nmgeek
fonte
1

A documentação diz que existe apenas uma variável de contexto form,.

Se você está tendo problemas com o login (o que é comum), a documentação diz que existem três variáveis ​​de contexto:

  • form: Um objeto Form que representa o formulário de login. Consulte a documentação dos formulários para obter mais informações sobre os objetos Form.
  • next: O URL para o qual redirecionar após o login bem-sucedido. Ele também pode conter uma string de consulta.
  • site_name: O nome do site atual, de acordo com a configuração SITE_ID.
S.Lott
fonte
2
A documentação diz que existe um "argumento opcional" chamado "template_name" que parece mais relevante.
jb.
O argumento opcional é um argumento para a função, não o contexto fornecido para o formulário.
S.Lott
Mmm- eu acho que a questão é confusa porque fala sobre 'contexto' quando na verdade tudo o que é relevante para resolver isso são os argumentos da password_resetvisão.
jb.
1

Eu estava usando essas duas linhas no url e o modelo do admin que eu estava mudando para minha necessidade

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
fonte