chamar duas view apartir de uma url

190 views
Skip to first unread message

dan

unread,
Jul 6, 2010, 9:25:26 PM7/6/10
to Django Brasil
Pessoal estou com um problema que acho que é bastante simples. Estou
perguntando aqui porque ainda não encontrei nas minhas pesquisas.

Situação:

# url do index:
(r'^$', 'views.index' ),

Ou seja a pagina inicial chama a view index. que faz algumas coisas e
chama o template index.

Problema:
Agora eu preciso que a pagina inicial chame a views.index e chame
também uma generic view:
"django.contrib.auth.views.login"

Ou seja uma template que vai receber dados de duas views, uma criada
por mim e outra uma generic view.

Alguem pode me ajudar?

Iuri

unread,
Jul 6, 2010, 9:30:29 PM7/6/10
to django...@googlegroups.com
O que você está tentando fazer?

Isso não me parece uma coisa normal a se fazer. Provavelmente tem um jeito melhor de fazer o que você está tentando.

[]s
iuri

2010/7/6 dan <dani...@gmail.com>

--
Django Brasil em Google Groups <http://groups.google.com.br/group/django-brasil>
Associe-se à Python Brasil e suporte nossa comunidade! <http://associacao.python.org.br/>

danilo silva dos santo

unread,
Jul 6, 2010, 9:39:30 PM7/6/10
to django...@googlegroups.com
Eu tenho uma template index.html, que receber dados de uma consulta atraves de minha " view.index"
mas eu quero agora que esse arquivo index.html, tenha uma area para fazer login.
eu tou lendo "aprendendo django no planeta terra", e la ele da como opção de criar uma pagina para fazer o login.(uma pagina especifica somente para fazer login - o que não me é util).No livro ele somente oferece como opção para fazer login usar essa generic view:
"django.contrib.auth.views.login" , não sei criar um login sem ela.

Marinho Brandao

unread,
Jul 6, 2010, 10:22:44 PM7/6/10
to django...@googlegroups.com
Danilo,

Como o Iuri disse, não é comum fazer o que você está tentando fazer, de certa forma é até impossível.

Mas caso esteja tentando forçar o login caso o usuário não esteja autenticado, ao entrar numa URL, dê uma olhada no decorator @login_required, em [1]

----
Marinho Brandão (José Mário)

danilo silva dos santo

unread,
Jul 6, 2010, 10:41:07 PM7/6/10
to django...@googlegroups.com
Pessoal desculpa,
mas acho que me entenderam errado, possivelmente me expressei errado...

eu apenas quero criar um form com login em minha pagina index, acontece que so sei criar um login usando generic views. E não consigo usar generic view porque ja uso uma view que eu criei.

Possivel solução, que eu não sei implementar:

não usar generic view, e na minha view, eu receber os dados do formulario (login) e buscar na tabela do admin(User)  admin(senha), 
if  usuario e senha batem{
   redireciono para pagina especifica do usuario
} else{
não permito login
}

Acho que agora ficou mais claro, programo em outras linguagens mais sou novo em python-django, essa situação é simples. 
Em resumo a duvida é como escrever uma view para tratar login e senha ( relativo ao cadastrado no admin).

obrigado pela ajuda.

Iuri

unread,
Jul 6, 2010, 10:44:34 PM7/6/10
to django...@googlegroups.com
Ao invés de utilizar a generic view, use o AuthenticationForm [1], passando ele para o template. Isso deve resolver o seu problema.

Vinicius Mendes

unread,
Jul 6, 2010, 10:53:10 PM7/6/10
to django...@googlegroups.com
Você cria o AuthenticationForm na sua views.index. Renderiza ele na index e coloca o action do form apra apontar para uma url que renderize uma view que tente fazer o login e redirecione para a index.

Atenciosamente,
Vinicius Mendes
Solucione Sistemas
vini...@solucione.info


2010/7/6 Iuri <iuris...@gmail.com>

Felipe Prenholato

unread,
Jul 7, 2010, 11:18:21 AM7/7/10
to django...@googlegroups.com
Do jeito que você disse, me pareceu que essa caixa de login aparecera em todo o site, pois é o que acontece quando você tem uma caixa de login na página principal e não uma página separada.

O que ti precisa fazer Danilo, é passar o request.POST pro authentication form, e este para a o template. Eu sugiro que essa validação do AuthenticationForm seja feita em um decorator ou um método extra, se este comportamento for válido para mais de uma view.

Ai embaixo tem um código de exemplo, eu não testei ele, mas é mais ou menos o caminho:

# o decorator
def sample_login_required(func):
    """
    Just check if user is logged or authenticate user
    """
    def wrap(request,*args,**kwargs):
        # se autenticado retorna de cara a view
        if request.user.is_authenticated():
            return func(request,*args,**kwargs)
        # se nao, faz a autenticacao, eu coloco o user e passwd antes para checar
        # se eles são algum valor, caso contrario eu nem passo pela validacao e
        # retorno o form vazio
        user = request.POST.get('username',None)
        passwd = request.POST.get('password',None)
        if user or passwd:
            request.authform = AuthenticationForm(data={'username':user,'password':passwd})
            if request.authform.is_valid():
                # loga o usuario se o user/pass for valido, trecho baseado na
                # view login do django.contrib.auth.views.login
                auth_login(request,request.authform.get_user())
            return func(request,*args,**kwargs)
        else:
            # se nem user nem passwd form valores, não passa na autenticacao e
            # só passa o form
            request.authform = AuthenticationForm()
            return func(request,*args,**kwargs)


# a view
@sample_login_required
def index(request):
    # sua view aqui
    return HttpResponse('hello world')

# o template:
<div id="userbox">
{% if request.user.is_authenticated %}
Olá {{ request.user.get_full_name }}.
{% else %}
{{ request.authform.as_p }}
{% endif %}
</div>


E em todo lugar que depender do usuario estar logado ou não, vc usa
request.user.is_authenticated :). Você pode se basear na view login para entender melhor o que foi feito :)
Felipe 'chronos' Prenholato.
Linux User nº 405489
Home page: http://chronosbox.org/blog
Twitter: http://twitter.com/chronossc

danilo silva dos santo

unread,
Jul 8, 2010, 8:58:10 AM7/8/10
to django...@googlegroups.com
Pessoal demorei para responder porque estava estudando mais os dados que voces informaram.
Acontece o seguinte.
Felipe passou uma solução, na qual eu devo, usar o action de meu form para uma url que vai chamar a view que contem o metodo que ele definiu "sample_login_required".
 
Contudo pelo que eu vi o django oferece uma solução mais elegante.
com formulario dinamico.
 
 
pelo que entendi ele oferece a opção de que eu não precise criar uma view para tratar o login,
não consegui usar isso, e não entendi a tag:  csrf_token e nem a ultilidade do input do tipo hidden.
 
Resumindo o problema novamente:
tenho um arquivo index.html que chamo atraves da url:
# url do index:
     (r'^$',  'views.index' ),
 
esse index.html extende base.html,
 
No arquivo base.html, eu quero deichar uma area de login, para tudo que extender base.html possa fazer login.
Contudo, teria que ter um url.py assim:
# url do index:
     (r'^$',  'views.index' ),
     (r'^$',  'django.contrib.auth.views.login',
        {'template_name': 'base.html'}, 'entrar'),
 
ou seja um local recebendo uma view criada por mim e uma generic view. Pois assim poderia usar em base.html:
 
So que isso não funciona.

George Ribeiro

unread,
Jul 8, 2010, 9:10:22 AM7/8/10
to django...@googlegroups.com
Já tive que fazer algo semelhante. A solução que eu encontrei foi
criar as views de login e logout no braço,
criei uma app plugável pra isso. Então no base.html fiz o form de
login também na mão onde o action apontava
para a view de login. No meu caso, isso resolveu o meu problema.

danilo silva dos santo

unread,
Jul 9, 2010, 12:20:06 AM7/9/10
to django...@googlegroups.com
Então voltamos a programar em PHP?
rrss..

Fiz a gambiarra, mas se alguem conseguir solução, posta ai..

obrigado a todos pelas ajudas.


--

Iuri

unread,
Jul 9, 2010, 1:01:11 AM7/9/10
to django...@googlegroups.com
Tive dificuldade para entender sua explicação, danilo, mas pelo que entendi você quer que o form esteja disponível em várias páginas, o que te forçaria a passar o form várias vezes (no caso, sempre que algum template estender de base.html), o que com certeza é trabalhoso e ruim.

Algumas coisas antes de te dar uma solução:

1) o urls.py que você colocou aí funciona diferente do que você imagina. O Django vai procurar nas urls UMA (e apenas uma) que combine com a url que você está entrando. Portanto, ao entrar em uma url que seja reconhecida pela regex ^$, o Django vai pegar só a primeira linha, a segunda nem será olhada.

2) o CSRF token, é uma solução para evitar ataques CSRF [1]. Sua única preocupação nesse caso é colocar o {% csrf_token %} no form, o Django cuida do resto.

3) o input hidden que é colocado ali é para definir para qual página o Django vai redirecionar o usuário depois do login.

4) Utilizar técnicas "PHP" no Django normalmente mostra que você está fazendo de um jeito errado.


Uma solução para o que você quer é um context_processor [2] que te retorne o AuthenticationForm. Pesquise sobre context processors do Django. Aí no template você usaria apenas algo como {% meu_form_de_login %}, deixando o resto para o context processor que você criou.

Não vou te passar código disso, porque o código em si é muito simples, você vai criar uma função que retorna um AuthenticationForm() (ou alguma variação dele). Mas tem que adicionar a função nos settings.TEMPLATE_CONTEXT_PROCESSORS (posso ter errado esse nome) e passar o RequestContext() nas views que você quiser chamar a função que você criou.
Reply all
Reply to author
Forward
0 new messages