Usando NewForms com ModelForm

Posted on Dezembro 10, 2007. Filed under: Django, Programação, Python | Tags: , , , |

É isso ae! To de volta para ajudar aqueles que estão quebrando a cabeça assim como eu estava a uns dias atrás para usar essas classes do django que facilitam muito o desenvolvimento. Eu ainda estou de boca aberta com o que o Django é capaz de fazer e hoje me pergunto “porque estou desenvolvendo em Delphi, ASP.NET e C# e ainda uso Windows?” pois bem isso é meu ganha pão e infelizmente não posso parar, mas se hoje me dessem uma oportunidade para trabalhar com Python e Django eu iria correndo!

Bom acho que esse tutorial merece ser explicado desde o inicio, desde a criação do projeto até os finalmente então vamos lá! Lembrando que é recomendado que se tenha a ultima versão do django do svn, para saber como instalar o django via svn consulte o site oficial ou o site da comunidade djangobrasil.org, os links são:
http://www.djangoproject.com/documentation/install/
http://www.djangoproject.com/download/

Tambem recomendo a leitura dos ótimos tutoriais feitos pelo nosso amigo Leandro no qual ele explica como instalar o Python e Django:
http://www.leandro.inf.br/2007/11/29/instalando-o-django/
http://www.leandro.inf.br/2007/11/28/instalando-o-python/
http://www.leandro.inf.br/2007/11/29/videos-do-artigo-instalando-o-django/

Criando o projeto, no console digite:
django-admin.py startproject tutorial
Teremos nosso projeto criado com o seguinte conteudo:
__init__.py manage.py settings.py urls.py
Bom com o nosso projeto criado vamos iniciar as configurações dos arquivos que o django-admin criou para nós na criação do projeto.
Vamos começar editando o arquivo settings.py, abra ele em seu editor preferido, eu estou usando o Eclipse com o PyDev, a instalação do pydev pode vir a se tornar mais um tutorial mais alem.
Eu vou mostrar aqui apenas os trechos em que vamo mecher para não ficar muito extenço:
DATABASE_ENGINE = ” # ‘postgresql_psycopg2′, ‘postgresql’, ‘mysql’, ’sqlite3′ or ‘oracle’.
DATABASE_NAME = ” # Or path to database file if using sqlite3.

Em DATABASE_ENGINE vamos colocar sqlite3 deixando a linha assim DATABASE_ENGINE = ’sqlite3′

Em DATABASE_NAME vamos colocar o caminho para o nosso banco de dados que no meu caso vai ficar assim DATABASE_NAME = ‘/home/raphal/Programacao/django/tutorial/dados.db’

Agora em TIME_ZONE = ‘America/Chicago’ vamos alterar para ‘America/Sao Paulo’

Em LANGUAGE_CODE = ‘en-us’ vamos alterar para ‘pt-br’

Em TEMPLATE_DIRS vamos adicionar o caminho para a nossa pasta que deve ser criada dentro da pasta do projeto, eu criei uma pasta chamada templates aonde vai ficar as nossas paginas html, no meu caso eu adicionei o caminho assim:
‘/home/raphal/Programacao/django/tutorial/templates’

Em INSTALLED_APPS vamos adicionar duas linhas, uma é para termos acesso ao site de administração do Django no qual poderemos ver, incluir e alterar os dados da nossa base de dados e a segunda linha é para indicarmos para o nosso projeto aonde esta a nossa aplicação que vamos criar daqui a pouco:
‘django.contrib.admin’,
‘tutorial.contatos’,

Dentro da nossa pasta do projeto no console vamos digitar o seguinte comando:
python manage.py startapp contatos

Esse comando vai criar uma pasta dentro do nosso projeto chamado “contatos” na qual vai estar os seguintes arquivos:
__init__.py models.py views.py

Ainda dentro da pasta do projeto digite:
python manage.py syncdb

Esse comando vai nos retornar o seguinte resultado:
Creating table auth_message
Creating table auth_group
Creating table auth_user
Creating table auth_permission
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table django_admin_log

You just installed Django’s auth system, which means you don’t have any superusers defined.
Would you like to create one now? (yes/no): yes

Diga yes para a pergunta do Django, ele vai criar uma conta de super usuario para que você tenha acesso ao site do admin, as seguintes linhas vao aparecer depois do yes:
Username (Leave blank to use ‘raphal’):
E-mail address: raphal@raphal
Password:
Password (again):
Superuser created successfully.
Installing index for auth.Message model
Installing index for auth.Permission model
Installing index for admin.LogEntry model

Agora vamos criar o nosso model para os contatos, dentro da pasta contatos abra o arquivo models.py e crie a seguinte classe que contera os campos do model ou tabela na qual os dados serao armazenados:

class Contatos(models.Model):
    nome = models.CharField(max_length=50)
    endereco = models.CharField(max_length=90)
    email = models.CharField(max_length=60)
    telefone = models.CharField(max_length=20)
    celular = models.CharField(max_length=20)
    class Admin:
        pass

Com isso uma tabela nova sera criada lá naquele arquivos que creiamos lembra? O dados.db e que quando usamos o syncdb ele foi gerado com as tabelas do admin, pois bem lah vai estar a nossa classe Contatos e os dados que vamos inserir nela tambem.
Rode o comando:
python manage.py syncdb

Isso vai criar a tabela lá no dados.db
Agora vamos para o arquivo views.py da aplicação “contatos”, abra ele e vamos adicionar as declarações que vamos utilizar, elas são as seguintes:

from django.shortcuts import render_to_response, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse
from django.newforms import ModelForm
from django.core.urlresolvers import reverse
from tutorial.contatos.models import Contatos

Ainda no views.py vamos criar nossa classe que vai ser chamada por uma função na qual ira criar o form e vai nos redirecionar para uma pagina html que ira receber esse form criado pelo modelo gerado lá no arquivo models.py

class ContatosModelForm(ModelForm):
    class Meta:
        model = Contatos

Essa é a nossa classe que recebe o model criado no models.py, se ela não recebe-se o model teriamos que declarar os campos um a um como fizemos lá no models.py, basicamente é a mesma coisa que fizemos no tutorial passado, aonde eu mostrei a mesma coisa só que ao invez de receber um model na classe eu fiz a classe com os campos.

No views.py vamos criar a função que vai chamar a classe ContatosModelForm e vai gerar o html com os campos do model:

def contatos(request):
    f = ContatosModelForm()
    return render_to_response('contatos.html',{'form':f.as_table()})

Criando a pagina html para que o form seja criado, o nome do arquivo deve ser contatos.html e deve ficar na pasta templates criada quando estavamos configurando o nosso projeto:

<html>
  <head>
    <title>Newforms Django</title>
  </head>
<body>
  <form action="/salvar_contato/" method="POST">
	  <table>
	    {{form}}
	  </table>
	  <input type="submit" value="Adicionar" />
  </form>
</body>
</html>

Essa é nossa pagina html, ali entre as tags <table> temos a variavel que vai receber o objeto form e é ali que o código html para o form sera gerado, ele esta entre as tags <table> porque vamos gerar o form com formatação em tabela. O que nos diz que o form vai ser gerado em formato de tabela é a opção do objeto “f” as_table() essa opção nos diz que o código html vai ser gerado em tabela.
Vocês podem ver tambem que estamos usando uma tag <form> com uma action=”/salvar_contato/” e o metodo dela é POST, a gente já vai chegar nessa parte, antes vamos criar o metodo utilizado para salvar os dados do formulário.

OK você quer ver o formulario aparecendo no browser não é? tá curioso! entao tá vamos configurar o nosso urls.py da seguinte forma:

(r'^admin/', include('django.contrib.admin.urls')),
      (r'^contatos/$', 'tutorial.contatos.views.contatos'),

A primeira linha vai estar comentada, descomente ela para termos acesso a area de administração do nosso projeto e adicione a segunda linha, essa linha vai ser o nosso link para a função contatos do nosso views na qual vai chamar o contatos.html e vai gerar o form.
Agora você já pode rodar o server usando o comando na pasta raiz do projeto:
python manage.py runserver

Esse comando vai subir o servidor interno do django usado somente para testes e debug, não é aconselhavel usar para outros fins, o endereço do servidor esta em http://127.0.0.1:8000/ acesse esse link em seu brownser caso o servidor tenha subido sem nenhum problema. Ops! Se você acessar esse endereço vai te retornar um erro 404, porque? Porque não criamos um index, não temos um site padrão para o endereço raiz “/”, na pagina do erro ele te mostra as opções de sites que temos em nosso urls.py entao acesse http://127.0.0.1:8000/contatos e pronto ai esta o nosso formulario, que coisa boa não? eu to impressionado até agora com isso, um form prontinho para ser usado, isso é django!

Agora sim vamos para a nossa função que vai salvar os dados do formulario:

def salvar_contato(request):
    if request.POST:
        f = ContatosModelForm(request.POST)
        if f.is_valid():
            c = f.save()
            return HttpResponseRedirect(reverse('tutorial.contatos.views.contatos_resultado', args=[c.id]))
        else:
            return HttpResponse(f.errors)

Essa função vai ser chamada no click do botao do nosso form que vai mandar um sinal POST e entao vamos salvar tudo o que foi digitado nos campos em um registro novo na nossa tabela contatos, mas claro que ele só vai salvar depois de ter certeza que esta tudo correto usando a opção “is_valid()”
Bom não adianta ir querendo testar agora pois ainda falta mais uma função pra ser criada que é a contatos_resultado pois quando formos gravar vamos querer ver os resultados ou em fim ir para algum outro lugar e não ficar na mesma tela do formulario.
Nossa função que ira nos mostrar os resultados do click no botao “Adicionar” é o seguinte:

def contatos_resultado(request, codigo):
    c = get_object_or_404(Contatos, pk=codigo)
    return render_to_response('contatos_lista.html', {'contato': c})

Vamos criar o arquivo contatos_lista.html:

<html>
  <head>
    <title>Newforms Django</title>
  </head>
<body>
   {{contato.nome}}<br />
   {{contato.endereco}}<br />
   {{contato.email}}<br />
   {{contato.telefone}}<br />
   {{contato.celular}}
</body>
</html>

Vamos adicionar nossas url lá no urls.py:

(r'^salvar_contato/$', 'tutorial.contatos.views.salvar_contato'),
(r'^contatos_resultado/(?P<codigo>\d+)/$', 'tutorial.contatos.views.contatos_resultado'),

É um exemplo bem simples, claro que vocês podem fazer algo melhor, isso foi feito só para vocês saberem que o registro foi gravado e vocês foram redirecionados para outra pagina. Após termos adicionado as urls já podemos testar a gravação de dados e a exibição deles, persebam que na ultima url adicionada eu passo o parametro para a url, entao se vocês por exemplo quiserem ver qualquer registro em contatos é só especificar um código no final da url no browser e os dados vão ser listados pois estamos chamando a função contatos_resultado e passando o parametro código para ele.

Bom por enquanto é isso, não vou continuar tudo nesse tutorial pois ainda tenho que estudar mais algumas coisas pois assim como vocês tambem estou aprendendo, nos proximos tutoriais vamos fazer uma visualização mais descente, alteração de dados e consultas, mas como ainda não sei bem como vou fazer tudo isso por enquanto ficamos por aqui mesmo, quando eu tiver mais resultados eu continuo o tutorial. Aceito ideias, sujestoes e criticas, oque vier é lucro ;)

Abraços!

Make a Comment

Make a Comment: ( 7 so far )

blockquote and a tags work here.

7 Responses to “Usando NewForms com ModelForm”

RSS Feed for Rafael (Core Dump) Comments RSS Feed

Parabéns pelo artigo, aprendi o que precisava sobre Django.

[]s

Mais uma vez um excelente artigo !!!.
Parabéns Rafael ! e muito obrigado pelas referencias.

Putz,
Que pena que o ModelForms só tem na versão do SVN, não tem na versão 0.96.
Fica ai a dica.

Oi Leandro!
Pois é o newforms é uma classe nova do django, na versão 1.0 do django que acho que vai sair em breve essa classe newforms vai se chamar apenas de forms, quando eles alterarem eu atualizarei o tutorial.
[]’s

Valeu.

Só uma observação…
No Model.py precisa importar o ModelForms…
por que se não apresenta esse erro:

class ServicoModelForm(ModelForm):
NameError: name ‘ModelForm’ is not defined

é só usar o:

from django.newforms import ModelForm

Mayron no tutorial eu declaro o
class ContatosModelForm(ModelForm):
class Meta:
model = Contatos
no views.py e nao no models.py, se vc declarou ele no models.py ai sim tem que chamar o ModelForm no models.py, não esqueça que o ContatosModelForm não é um model e sim uma classe que chama um model.


Where's The Comment Form?

Liked it here?
Why not try sites on the blogroll...