Formulários no Django

Postado em: Fevereiro 21, 2008
Tags: django

Olá pessoal, no meu ultimo artigo Excluindo e atualizando os dados ModeForm eu cometi um erro, não coloquei no artigo e nem no exemplo a função para alterar os dados, então ele fico apenas adicionando e excluindo os dados. Para corrigir isso eu vou por meio desse artigo explicar passo a passo todas as operações de um formulário básico em Django usando ModelForm.
O código fonte do exemplo você pode encontrar no final desse artigo.

Crie um projeto e uma aplicação novos, nesse artigo o nome do projeto vai ser "tutorial" e o nome da aplicação é "tuto2".

Vamos ao nosso models.py:

# -*- coding: utf-8 -*-
from django.db import models

class Clientes(models.Model):
cli_codigo = models.AutoField('Código', primary_key=True, db_index=True)
cli_nome = models.CharField('Nome', db_index=True, max_length=100)
cli_fantasia = models.CharField('Fantasia', db_index=True, max_length=100)

class Admin:
pass

def __unicode__(self):
return self.cli_nome


Nosso model é bem simples, com três campos apenas, não requer nem maiores explicações, mas se você tiver alguma duvida consulte minha tradução resumida Model referencia (resumido e editado)
Agora vamos para o nosso views.py, primeiro tenha as seguintes declarações no inicio do arquivo:
# -*- coding: utf-8 -*-
from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.newforms import ModelForm
from tutorial.tuto2.models import Clientes

Com essas declarações agora estamos prontos para criar nossas funções básicas para um formulário de cadastros.
Nossa primeira função é a "index", ela se encarrega de carregar todos os dados já cadastrados e é ela que gera a pagina inicial do nosso exemplo:
def index(request):
clientes = Clientes.objects.all()
return render_to_response('index.html', {'clientes':clientes,})

Com os dados carregados então temos que criar nossa página já com os dados contidos nela, e é para isso que o “render_to_response” serve, ele renderisa a pagina, no nosso caso o “index.html” e manda para ela o conteúdo no qual será usado dentro do nosso template (index.html).

Nossa próxima função é a “adicionar_cliente”:

def adicionar_cliente(request):
if request.POST:
f = ClientesModelForm(request.POST)
if f.is_valid():
c = f.save()
return HttpResponseRedirect(reverse('tutorial.tuto2.views.index'))
else:
return HttpResponse(f.errors)
else:
f = ClientesModelForm()
return render_to_response('adicionar_cliente.html', {'form':f.as_table(),})

O que fazemos nela é verificar se no template “adicionar_cliente.html” foi executado um “POST” de um formulário usando para isso o objeto “request”, para mais detalhes sobre o “request” consulte request_response
Entrando nesse “if” pegamos os dados do formulário e mandamos para a nossa classe que contem o nosso model “Clientes”. Verificamos se todos os campos estão corretos e então gravamos com o “save()”. Logo após salvar os dados no banco retornamos para a nossa página inicial com os dados atualizados, nosso recém adicionado cliente estará na lista agora. O “HttpResponseRedirect” nos redireciona para outra página, junto com o “reverse” ele nos joga diretamente para a função que queremos, com isso evitamos que a url no browser fique assim por exemplo (http://127.0.0.1:8000/ adicionar_cliente/).
O “HttpResponse” retorna o que estiver entre ( ), nesse caso ele estará retornando quais os campos deram problemas com “f.errors”, claro que essa não é a melhor maneira de se fazer isso, você pode usar outros métodos para mostrar uma página com os erros mais legíveis para o usuário final.
Se não estivermos em um “POST” então apenas retorne o formulário vazio, é isso que o “else” faz, manda para o “adicionar_cliente.html” um formulário vazio e formatado para que fique em forma de tabela html com a opção “as_table”.

Vamos para a função “alterar_cliente”:

def alterar_cliente(request, codigo):
cliente = get_object_or_404(Clientes, pk=codigo)
f = ClientesModelForm(request.POST, instance=cliente)
if f.is_valid():
cliente = f.save()
return HttpResponseRedirect(reverse('tutorial.tuto2.views.index'))
else:
return HttpResponse(f.errors)

Passamos para essa função o código do cliente que queremos alterar, com o código em mãos vamos carregar os dados dele para que possamos aplicar os novos dados alterados.
A função “get_object_or_404” pega os dados do objeto “Clientes” informando pelo parâmetro “pk” que eu quero os dados do cliente que seja igual ao código contido na variável “codigo”, se não encontrar ele retorna uma página de erro 404 (Página não encontrada).
Com os dados do cliente guardados na variável “cliente” então enviamos para a nossa classe, aquela que gera os formulários a partir do model e armazena os dados do nosso objeto “Clientes” a ClientesModelForm. Com o “request.POST” pegamos todos os dados do formulário que foi preenchido ou alterado pelo usuário e mandando para a classe ClientesModelForm estaremos alterando os dados originais que enviamos através da variável “cliente” que nada mais é do que um objeto da “Clientes” que contem todos os dados que solicitamos anteriormente.
Daí em diante e feita a verificação e se tudo estiver certo então salvamos os dados.

A função “apagar_cliente”:

def apagar_cliente(request, codigo):
cliente = get_object_or_404(Clientes, pk=codigo)
cliente.delete()
return HttpResponseRedirect(reverse('tutorial.tuto2.views.index'))

É bem simples, selecionamos o cliente, e o apagamos com o “delete()”

Mostrando os dados de um cliente no formulário para que possamos alterar ou excluir o cliente selecionado com a função “mostra_dados_cliente”:

def mostra_dados_cliente(request, codigo):
cliente = get_object_or_404(Clientes, pk=codigo)
codigo = cliente.cli_codigo
f = ClientesModelForm(instance=cliente)
return render_to_response('cliente_dados.html', {'form':f.as_table(), 'codigo':codigo})

Selecionamos o cliente, pegamos o código dele e geramos um formulário com os dados retornados pela consulta do “get_object_or_404”, com essas poucas linhas temos um formulário e o código do cliente para que possamos alterar ou excluir ele.

A classe “ClientesModelForm” é a responsável por gerar os formulários html com base em nosso model, no caso “Clientes”.

class ClientesModelForm(ModelForm):
class Meta:
model = Clientes

Não explicarei aqui sobre o urls.py pois ela esta bem simples de se entender, mas mesmo que tenha duvidas fique a vontade para comentar, segue o código das urls:

(r'^admin/', include('django.contrib.admin.urls')),
(r'^$', 'tutorial.tuto2.views.index'),
(r'^adicionar_cliente/$', 'tutorial.tuto2.views.adicionar_cliente'),
(r'^alterar_cliente/(?P<codigo>\d+)/$', 'tutorial.tuto2.views.alterar_cliente'),
(r'^apagar_cliente/(?P<codigo>\d+)/$', 'tutorial.tuto2.views.apagar_cliente'),
(r'^mostra_dados_cliente/(?P<codigo>\d+)/$', 'tutorial.tuto2.views.mostra_dados_cliente'),

Vamos aos códigos das paginas html:
index.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Tutorial RFDev.org</title>
</head>
<body>
<a href="/adicionar_cliente/">Adicionar Cliente</a><br /><br />
{% for clientes in clientes %}
<a href="/mostra_dados_cliente/{{ clientes.cli_codigo }}/">{{ clientes.cli_nome }}</a><br />
{% endfor %}
</body>
</html>

adicionar_cliente.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Tutorial RFDev.org</title>
</head>
<body>
<form action="/adicionar_cliente/" method="post">
<table>
{{form}}
</table>
<input type="submit" value="Adicionar"/>
</form>
</body>
</html>

cliente_dados.html

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"/>
<title>Tutorial RFDev.org</title>
</head>
<body>
<form action="/alterar_cliente/{{ codigo }}/" method="post">
<table>
{{form}}
</table>
<input type="submit" value="Salvar"/>- <a href="/apagar_cliente/{{ codigo }}/">Excluir</a>
</form>
<a href="/">Voltar</a>
</body>
</html>

Espero que aproveitem e estou a disposição para tirar as duvidas e discutir sobre o artigo.
Até a próxima!

Código fonte exemplo: exemplo



Não será divulgado!

Um site válido!

Renata em Fevereiro 25, 2008

OK! Testado e funcionando.

Mayron Cachina em Fevereiro 26, 2008

Ta vendo.... Bem que eu disse na época, vc n escutou :D

[]´s

Hercules em Abril 19, 2008

Achei muito interessante sua divulgação e ainda mais a correção.
Isto demonstra que nao só seu entusiasmo como também seu apoio.
Porisso venho pedir ajuda;
Tentei incluir em meu projeto e apareceu erro tentei encontrar uma solução mas sem sucesso, então fiz exatamente como o exemplo, mas o erro é o mesmo:"Exception Value: __init__() takes at least 2 arguments (1 given)" ao tentar adicionar clientes.

Será que poderia me ajudar neste caso?
Agradeço antecipadamente

Outros

Hospedagem gratuitamente cedida pela TeHospedo - Hospedagem de sites, registro de dominios, revenda de hospedagem, streaming
TeHospedo - Hospedagem de sites, registro de dominios, revenda de hospedagem, streaming

django donated

pyconbrasil

Divulgue o Nerdson

Firefox 3 - Brazil

BlogBlogs

Add to Technorati Favorites

Django
Desenvolvido com Django, Aptana, Gimp, Inkscape | Rafael Campos de Bastiani - RFDev.org - 2008