Criando as Views
Antes de começarmos a falar sobre as views, vamos configurar o arquivo urls.py e mapear nossas URLs. Não detalharemos esse processo muito menos sobre expressões regulares utilizadas.
Vamos mapear todos as nossas views de uma vez, alterando novamente a variável urlpatterns dentro do arquivo urls.py:
1 2 3 4 5 6 7 8 9 | urlpatterns = patterns('', (r'^admin/(.*)', admin.site.root), (r'^cliente/list/$','sigep.cliente.views.list'), (r'^cliente/add/$','sigep.cliente.views.add'), (r'^cliente/delete/$','sigep.cliente.views.delete'), (r'^cliente/edit/$','sigep.cliente.views.edit'), (r'^cliente/update/$','sigep.cliente.views.update'), (r'^cliente/search/$','sigep.cliente.views.search'), ) |
Agora sim, vamos ao que interessa…
No Django as views são os controllers do modelo MVC, ou seja, métodos que intermediam a comunicação entre os modelos (banco de dados) e os templates (HTML).
Vamos escrever nossos métodos no arquivo views.py localizado dentro do diretório da aplicação cliente:
Método 1: list
Descrição: Exibe os clientes cadastrados e um formulário para cadastrar novo cliente. Na realidade o template exibido é o clienteform que por sua vez extende o template clientes.html, resultando na exibição dos 2 ao mesmo tempo.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # -*- coding: utf-8 -*- from sigep.cliente.models import * from sigep.cliente.forms import * from django.shortcuts import render_to_response def list(request): clienteform = ClienteForm() clientes = Cliente.objects.all() bairros = Bairro.objects.all() return render_to_response('clienteform.html',{ 'form':clienteform, 'clientes':clientes, 'bairros':bairros, 'operacao':'Cadastrar', }) |
Explicando o código:
Definimos a codificação do arquivo como UTF8
Criamos um objeto do tipo ClienteForm, que foi definido no arquivo forms.py
A variável clientes obtem todos os clientes cadastrados
A variável bairros obtem todos os bairros cadastrados
O metodo listar retorna o arquivo de template a ser renderizado com o valor das variáveis passadas como argumentos.
Método 2: add
Descrição: Cadastra os dados do cliente no banco de dados.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | from django.http import HttpResponse def add(request): if request.method == 'POST': clienteform = ClienteForm(request.POST) if clienteform.is_valid(): clienteform.save() mensagem = 'Cadastro realizado com sucesso.' else: mensagem = 'Erro na validacao do form.' clientes = Cliente.objects.all() operacao = 'Cadastrar' return render_to_response('clienteform.html',{'form':clienteform, 'clientes':clientes, 'mensagem':mensagem, 'operacao':operacao}) else: return HttpResponse("Nao foi submetido nenhum formulario.") |
Notem o quanto a validação de um formulário é ridiculamente simples no Django. É criado um objeto do tipo ClienteForm, passando como parâmetro o formulário submetido e chamando o método is_valid().
Uma novidade nesse código foi o uso do método HttpResponse que apenas exibe um texto na tela do navegador.
Método 3: delete
Descrição: Remove o cliente do banco de dados a partir do id fornecido.
1 2 3 4 5 6 7 8 9 10 11 | def delete(request): if request.method == 'POST': id = request.POST.get('listaclientes') if id > 0: Cliente.objects.get(pk=id).delete() return HttpResponseRedirect('/cliente/list/') else: return HttpResponse("Nenhum cliente foi selecionado. Id=0.") else: return HttpResponse("Nao foi submetido nenhum formulario.") |
Em
1 | Cliente.objects.get(pk=id) |
, estamos selecionando na tabela cliente o registro cuja chave primária (pk) seja igual ao valor da variável id. Essa variável poderia ter outro nome, e não necessáriamente o nome do campo da tabela que também é id.
Método 4: edit
Descrição: Obtém os dados do cliente a partir do id fornecido e preenche o formulário usado no cadastro.
1 2 3 4 5 6 7 8 9 10 11 12 13 | def edit(request): if request.method == 'POST': id = request.POST.get('listaclientes') if id > 0: clientes = Cliente.objects.get(pk=id) clienteform = ClienteForm(instance=clientes) form_url = '/cliente/update/' operacao = 'Atualizar' return render_to_response('clientes.html' {'form':clienteform, 'id_cliente':id, 'form_url':form_url, 'operacao':operacao}) else: return HttpResponse("Nenhum cliente foi selecionado. id=0.") else: return HttpResponse("Nao foi submetido nenhum formulario.") |
Método 5: update
Descrição: Atualiza os dados do cliente e tenta fazer a validação do mesmo jeito que o método add.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | def update(request): if request.method == 'POST': id = request.POST.get('id') if id > 0: cliente = Cliente.objects.get(pk=id) clienteform = ClienteForm(request.POST,instance=cliente) if clienteform.is_valid(): clienteform.save() return HttpResponseRedirect('/cliente/list/') else: mensagem = 'erro' operacao = 'Atualizar' return render_to_response('clienteform.html',{'form':clienteform, 'mensagem':mensagem, 'id_cliente':id, 'operacao':operacao}) else: return HttpResponse("Nenhum cliente foi selecionado. id=0.") else: return HttpResponse("Nao foi submetido nenhum formulario.") |
Método 6: search
Descrição: A partir da palavra-chave fornecida, é feita uma busca case-insensitive na tabela cliente nos campos nome e cpf. Equivalente em SQL à WHERE nome LIKE “%palavra%” OR cpf LIKE “%palavra%”. Para tal tarefa vamos utilizar o objeto Q, pertecente à biblioteca django.db.models.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | def search(request): if request.method == 'POST': palavra = request.POST.get('busca') if len(palavra) > 0: from django.db.models import Q clientes = Cliente.objects.filter(Q(nome__icontains=palavra) | Q(cpf__icontains=palavra)) bairros = Bairro.objects.all() clienteform = ClienteForm() return render_to_response('clienteform.html',{ 'form':clienteform, 'clientes':clientes, 'bairros':bairros, 'operacao':'Cadastrar', 'titulo':'RESULTADO DA BUSCA' }) else: return HttpResponse("Nao foi digitado nada no campo de busca.") else: return HttpResponse("O formulario nao foi submetido.") |
Terminamos de criar nossas views, entretanto nosso sistema não possui a mínima segurança. Vamos criar então nossa interface de autenticação de usuários.
Autenticação de Usuários
Nosso método de autenticação será o mesmo utilizado pelo admin. Criaremos apenas a interface de login, um template simples, e todo o processo de autenticação e validação será feito pelo Django.
Na primeira vez em que foi executado o script manage.py syncdb, o Django perguntou se você queria criar uma conta de super-usuário. Essa é a mesma conta usada pelo admin. Se por acaso você não criou essa conta, execute o comando abaixo para criar um novo:
gu@notebook:~/projetos/sigep$ ./manage.py createsuperuser
Vamos criar nosso template de login, dentro do diretório de templates, com o nome loginform.html:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>SIGEP - Login</title> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <script language="Javascript" type="text/javascript"> function Validar(objForm) { if (objForm.username.value != "" && objForm.password.value != "") return true; else { alert("Preencha corretamente todos os campos."); objForm.username.focus(); return false; } } </script> </head> <body> <center> <form action="." name="login" id="frmLogin" method="post" onsubmit="return Validar(this)"> <div id="divLogin" align="left"> <br />Usuario: {{form.username}} <br />Senha: {{form.password}} <input type="hidden" name="next" value="{{ next }}" /> <br /><br /> <input type="submit" name="btOk" value="Ok" /> </div> </form> {% if form.errors %} <div align="center" style="padding-top:50px;font-size:16px;color:red;"> Erro: Usuario ou senha incorretos. </div> {% endif %} </center> </body> </html> |
Nosso template é um arquivo HTML simples, com uma função Javascript que verifica se os campos usuario e senha foram preenchidos e então envia o formulário. No action foi inserido um ponto (.) porque o método que vai renderizar esse template automaticamente substituirá pelo action verdadeiro.
E então vamos fazer o mapeamento de URL para o processo de login. No arquivo urls.py, adicione na variável urlpatterns o seguinte:
1 2 | r'^auth/login/$','django.contrib.auth.views.login', {'template_name': '/home/gu/projetos/sigep/templates/loginform.html'}), (r'^auth/logout/$','django.contrib.auth.views.logout_then_login'), |
Observem que não estamos fazendo um mapeamento para nenhuma das views que criamos, pois o Django provê métodos próprios para esse tipo de autenticação. Definimos apenas o template que criamos anteriormente para ser usado.
Existem 3 variáveis que não vêm definidas por padrão e que são necessárias para a autenticação funcionar. Vamos defini-las então no arquivo settings.py:
1 2 3 | LOGIN_URL = '/auth/login/' LOGOUT_URL = '/auth/logout' LOGIN_REDIRECT_URL = '/cliente/list/' |
LOGIN_URL e LOGOUT_URL devem ter o mesmo valor que foi utilizado no mapeamento de URL logo acima. LOGIN_REDIRECT_URL é a view a ser chamada quando o login for efetuado.
Para finalizar essa parte, precisamos definir quais das nossas views só poderão ser acessadas se o usuário estiver logado. Para isso vamos utilizar o método login_required() presente na biblioteca django.contrib.auth.decorators.
No arquivo views.py, devemos importar o método login_required. Para cada view que seja necessário o login efetuado, devemos declarar uma variavel com o mesmo nome da view, recebendo o valor de login_required passando como argumento a view. Ex.:
1 2 3 4 | from django.contrib.auth.decorators import login_required def welcome(request): return HttpResponse('Bem-vindo! Voce esta logado no sistema.') welcome = login_required(welcome) |
Conforme o exemplo acima, vamos usar o login_required() abaixo de cada view que escrevemos.
1 2 3 4 5 6 7 | def list(request): ... list = login_required(list) def add(request): ... add = login_required(add) |
Nossa aplicação está quase completa. Está faltando o uso do ajax para exibir as ruas cadastradas a partir do bairro selecionado.














Posted in
Tags: 
Muito legal o tuto, parabéns!!
Hugs!!
Muito bom, dei só uma olhada mas com esse tipo de material o Django ira crescer cada vez mais.
Fala rapaz parabens ai ficou muito bom ,,
uma abraço
Gustavo,
Meus sinceros parabéns pelo material, está excelente.
Um desafio:
– O que tu achas de fazer uma versão desse ajax com a biblioteca mootools ?
Parabéns Gustavo,
Ouvi falar da eficiência do Django a poucos dias e procurei algo simples que pudesse me comprovar isso…
Vc sintetizou nesse post tudo o que eu estava procurando! Agora é só me aprofundar no framework. Se existirem mais posts como esse por aí tenho certeza que a comunidade Python e Django vão crescer muito em quantidade e principalmente em qualidade! 100% produção…
Verifiquei que no arquivo forms.py ao usarmos o método mark_safe, devemos incluir a classe safestring do Django.
Para resolver o problema devemos incluir a linha from django.utils.safestring import mark_safe no início do arquivo /cliente/forms.py para importar o método mark_safe.
Abs…
na linha
$(“#”+objHtmlReturn).append(”+item.fields[fieldreturn]+”);
qd escolho o bairro da um erro dizendo q a palavra ou o campo “fieldreturn” nao está definido por isso nao carrega as ruas no outro select
Excelente tutorial, colega.
Parabéns XD
Opa, tudo bom.
Primeiro quero parabenizá-lo pelo artigo. Segundo informo que o método javascript declarado acima para atualizar o select html está quebrado. Criei outro método jQuery, que ficou assim:
$( function() {
$(“select#id_bairro”).change(
function() {
$.getJSON( “/cliente/getlogradouros?id=” + $(this).val(),
function(j) {
var options = ‘———- ‘;
for ( var i = 0; i < j.length; i++) {
options += ”
+ j[i].fields['logradouro']
+ ”;
}
$(“#id_logradouro”).html(options);
$(“#id_logradouro option:first”).attr(’selected’,
’selected’);
$(“#id_logradouro”).attr(‘disabled’, false);
})
$(“#id_logradouro”).attr(’selected’, ’selected’);
})
})
Para que ele funcione, o metodo no módulo views.py precisa ser mudado para o método GET, que no meu caso ficou assim:
def getlogradouros( request ):
id = int( request.GET.get( ‘id’ ) )
lista = Logradouro.objects.filter( bairro = id )
if lista.count() > 0:
json = serializers.serialize( “json”, lista )
else:
lista = [{"pk":"0", "fields":{'logradouro':"Nenhum registro"}}]
json = simplejson.dumps( lista )
return HttpResponse( json, mimetype = “application/json” )
Ola gostei do material que vc publicou, vc terminou a segunda parte deste tutorial referente ao sistema???
@Luiz, nao cheguei a terminar, mas escrevi um artigo aqui no blog que fala um pouco sobre. O titulo é “Servidor Linux com Proxy e Controle de Banda”.
[]’s