SlideShare una empresa de Scribd logo
1 de 96
django : Web Framework

                 Treinamento Básico

     Entendendo django
         na prática!
Leandro Zanuz
Twitter: @leandrozanuz
Setembro de 2010
Cronograma

✤ Introdução;
✤ Criando e Configurando um Projeto;
✤ Models;
✤ URL Dispatcher;
✤ Views;
✤ Templates;
✤ Middlewares;
✤ Forms.
                                       2
O que é django
✤ Um framework web desenvolvido com a
liguagem python;
✤ Adota o padrão MVC (Model-View-Controller);
✤ Ênfase em reusabilidade e plugabilidade;
✤ Desenvolvimento ágil;
✤ Baseado no conceito DRY (Don't Repeat
Yourself);
✤ Mapeamento objeto-relacional ORM;
✤ Código aberto (open source).                  3
Arquitetura básica (MVC)




                                                                  4

                http://www.aprendendodjango.com/gallery/fluxo-no-mvc/file/
O django-admin.py

✤ O django-admin.py deverá estar no “path” do
sistema se você instalou o django via python setup.py.

✤ Se ele não estiver no path, você poderá encontrá-lo
em site-packages/django/bin, onde site-packages é um
diretório dentro da sua instalação do python.

✤ Considere a possibilidade de criar um link simbólico
para o django-admin.py em algum lugar em seu path,
como em /usr/local/bin.
                                                         5
Criando o projeto

✤ Executando o comando a baixo, será criada a
seguinte estrutura de arquivos do projeto:

  python django-admin.py startproject meusite
__Init__.py : Arquivo de configuração para o python
reconhecer a pasta do projeto como um pacote.
manage.py : Script para execução de tarefas
administrativas do projeto.
settings.py : Configurações do projeto.
urls.py : Configuração das URLs do projeto.           6
Será que funciona?

✤ Vamos verificar se o projeto funciona. Vá para o
diretório meusite, se você ainda não estiver nele, e rode o
comando “python manage.py runserver 8000”. Você verá a
seguinte saída na sua linha de comando:

Validating models...
0 errors found

Django version 1.3 pre-alpha SVN-13679, using settings 'meusite.settings'
Development server is running at http://127.0.0.1:8000/
Quit the server with CONTROL-C.

                                                                            7
Testando no navegador

✤ Com o servidor rodando, visite http://127.0.0.1:8000/
com seu navegador Web. Você irá ver a página "Welcome
to Django", em agradáveis tons de azul claro pastel. Ele
funcionou!




                                                       8
Anote e lembre-se

✤ Uma boa hora para ANOTAR:

✤ NÃO utilize este servidor em nada relacionado a
um ambiente de produção. Este servidor tem como
objetivo ser utilizado apenas durante o desen-
volvimento.

✤ Django é um framework, não um servidor web!


                                                9
Banco de dados

✤ Vamos utilizar o banco de dados SQLite para este
projeto. Caso o SQLite não esteja instalado, “sudo apt-get
install sqlite3”. No arquivo settings.py do projeto vamos
fazer as configurações necessárias:
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'meusite.db'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
✤ Aṕos salvar o arquivo execute “python manage.py syncdb”.
LEMBRE-SE de anotar o usuário e a senha do super usuário. 10
PySQLite

✤ Dica: Caso o python não possua o módulo do SQLite
instalado “No module named _sqlite3”, você deverá
instalar o pacote “sudo apt-get install python-sqlite” ou
baixar PySQLite do site:
http://code.google.com/p/pysqlite/

✤ Se você fizer download módulo e estiver utilizando
um ambiente Linux, será necessário instalar a lib
“sudo apt-get install libsqlite3-dev” para compilar o
módulo.
                                                       11
Testando a base de dados

✤ Após configurar a base de dados, podemos
verificar se a estrutura de tabelas está OK.
.../meusite$ sqlite3 meusite.db
SQLite version 3.7.2
Enter ".help" for instructions
sqlite> .schema

✤ Você deverá ver diversas instruções “CREATE
TABLE” referente as tabelas administrativas
necessárias pelo framework.
                                           12
Criando uma aplicação

✤ Dentro da pasta meusite criada anteriormente,
execute o comando a seguir. Será criada a seguinte
estrutura de arquivos:

  python django-admin.py startapp musicos

__Init__.py : Arquivo de configuração para o python
reconhecer a pasta da aplicação como um pacote.
models.py : Arquivo onde serão definidos os modelos.
views.py : Arquivo que irá conter as views da aplicação.
                                                           13
Adicionando a aplicação

✤ Vamos editar o settings.py novamente, alterar
a linguagem para “pt-br” e adicionar a
aplicação “musicos“ as apps instaladas.
LANGUAGE_CODE = 'pt-br'
....
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.admin',
                                             14
'musicos' )
Models




         15
Models

✤ Camada de abstração do banco de dados;
✤ São classes que herdam de   django.db.models.
Model;
✤ Definem as entidades do sistema;

✤ Cada atributo de classe do modelo representa
uma coluna do banco de dados.
✤ Já possui diversos tipos de colunas no banco
de dados (ex: INTEGER, VARCHAR).
                                                  16
Models
from django.db import models
class Artista(models.Model):
  nome = models.CharField(max_length=50, null=False)
  sobrenome = models.CharField(max_length=50)
  data_nascimento = models.DateField(null=False,
                     db_column='data_de_nascimento')
class Album(models.Model):
  artista = models.ForeignKey(Artista)
  descricao = models.CharField(max_length=100)
  data_lancamento = models.DateField()
  valor_venda = models.DecimalField(max_digits=5,
                 decimal_places=2, null=False)
http://docs.djangobrasil.org/ref/models/fields.html#common-model-field-options          17
http://docs.djangobrasil.org/howto/custom-model-fields.html#howto-custom-model-fields
Models

✤ Cada tipo de campo recebe um certo conjunto de
argumentos específicos. Por exemplo, CharField (e
suas subclasses) requerem um argumento max_length
que especifica o tamanho do campos VARCHAR que
será usado para armazenar os dados.

✤ Há um conjunto de argumentos comuns disponí-
veis para todos os tipos de campos. Todos são
opcionais e são totalmente explicados na referência:

http://docs.djangobrasil.org/ref/models/fields.html#common-model-field-options   18
Models

✤ O metadado do model é "qualquer coisa que não seja
um campo", assim como opções de ordenamento (attr:
Options.ordering), nome de tabelas do banco de
dados (db_table), ou nomes legíveis-por-humanos no
singular ou plural (verbose_name_plural).
✤ Nenhum é obrigatório, e adicionar class Meta ao
model é completamente opcional.
 class Meta:
    db_table='artista'
                                                                          19
http://docs.djangobrasil.org/ref/models/options.html#ref-models-options
Models

✤ Aṕos editar o arquivo models.py execute novamen-
te “python manage.py syncdb”.
Creating tables ...
Creating table artista
Creating table album
Installing custom SQL ...
Installing indexes ...
No fixtures found.

✤ Note que neste momento as tabelas artista e album
foram criadas. Agora vamos começar a manipular
dados utilizando os modelos criados.         20
Models

✤ Para utilizarmos o django ADMIN, vamos editar o
arquivo urls.py que está na pasta do projeto e
remover o comentário das linhas a seguir:
# Remova o comentário das duas próximas linhas para ativar o admin:
# from django.contrib import admin
# admin.autodiscover()

# Uncomment the next line to enable the admin:
# (r'^admin/', include(admin.site.urls)),

✤ Localize estas linhas em seu arquivo urls.py e remova o
comentário das linhas que possuem o # vermelho.                       21
Models

✤ Também editar o arquivo settings.py que está na
pasta do projeto e remover o comentário da linha a
seguir:
INSTALLED_APPS = (
   ...
  # Uncomment the next line to enable the admin:
  # 'django.contrib.admin',
   …)
#Lembre-se de fazer a sincronização após adicionar uma nova app:
>>> python manage.py syncdb

✤ Localize a propriedade INSTALLED_APPS e remova o
                                                                   22
comentário da linha que possuem o # vermelho.
Models

✤ Para conectar o modelo a interface administrativa,
vamos criar o arquivo admin.py dentro da aplicação
musicos para registrar os modelos que devem ser
manipulados via ADMIN:
from django.contrib import admin
from models import Artista, Album

admin.site.register(Artista)
admin.site.register(Album)

✤ No arquivo admin.py são registrados os modelos que
                                                  23
podem ser manipulados pelo ADMIN.
Models

✤ Para concluirmos a configuração básica do ADMIN,
vamos editar novamente o arquivo models.py da
aplicação musicos e adicionar uma descrição para
cada classe do modelo:
class Artista(models.Model):
  ….
  def __unicode__(self):
     return "%s %s" % (self.nome,self.sobrenome)
class Album(models.Model):
  ….
  def __unicode__(self):
     return self.descricao                         24
Models

✤ Concluídas as alterações básicas necessárias, vamos
testar o ADMIN. Aqui será necessário o usuário e a
senha do superusuário definidas no syncbd.
✤ Acesse com seu navegador http://127.0.0.1:8000/admin/




                                                          25
Models

✤ Agora utilizaremos o comando “python manage.py
shell“. O manage.py configura o ambiente do projeto
para você. Vamos começar a trabalhar com models:
# Import das classes do model que acabamos de criar.      Vamos incluir
>>> from musicos.models import Artista, Album            diversos artistas
                                                       para melhor ilustrar
                                                           os exemplos
# Não há nenhum registro nas tabelas ainda.                  a seguir.
>>> Artista.objects.all()
# Adicionando o primeiro Artista.
>>> from datetime import datetime
>>> a = Artista(nome='Leandro', sobrenome='zanuz',
                data_nascimento=datetime(1980,5,20))
>>> a.save()                                                                  26
Models
# Note que após salvar o objeto “a” ele passa a possuir um identificador (id).
>>> a.id
# Acessando atributos do objeto.
>>> a.nome
>>> a.sobrenome
# Alterando dados do objeto Artista.
>>> a.sobrenome = 'Zanuz'
>>> a.save()
# Selecionando um objeto Artista específico.
>>> Artista.objects.get(id=1) ou (pk=1)
# Listando todos os objetos Artista cadastrados.
>>> Artista.objects.all()
                                                                                 27
Models

✤ Para selecionar registros do banco de dados, você
deverá construir uma QuerySet utilizando as classes do
models.
✤ Uma QuerySet representa uma coleção de objetos de
seu banco de dados. Ela pode conter zero, um ou muitos
filtros (critérios que restringem a coleção baseado em
argumentos fornecidos).
✤ Equivalente ao SQL, a QuerySet representa uma
expressão SELECT, e os filtros são cláusulas limitadoras
como o WHERE ou LIMIT.                                 28
Models
# Também podemos selecionando UM objeto pelo nome e/ou sobrenome.
>>> a = Artista.objects.get(nome='Leandro',sobrenome='Zanuz')
>>> a.id

>>> a = Artista.objects.get(data_nascimento__year = 1980)
>>> a.id

✤ Utilizando filtros em uma QuerySet:
filter(**kwargs)
   Retorna uma nova QuerySet contendo somente os objetos que
satisfazem os argumentos especificados.
exclude(**kwargs)
   Retorna uma nova QuerySet contento somente os objetos que não
                                                              29
satisfazem os argumentos especificados.
Models

✤     Para definir as cláusulas WHERE da QuerySet
utilizamos os chamados “field lookups“, que são
palavras chave específicas utilizadas nos métodos
filter(), exclude() e get().

✤ Como utilizar os lookups: field__lookuptype=value
(__ é um duplo underscore).
>>> Artista.objects.filter(data_nascimento__lte='1982-1-1')
SELECT * FROM artista WHERE data_nascimento <= '1982-1-1';
                                                                           30
http://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups
Models
# Note que utilizando filtros não ocorre erro ao retornar MAIS DE UM objeto.
>>> Artista.objects.filter(data_nascimento__year=1980)
# Filtrando objetos que o nome inicie com “Lean”.
>>> Artista.objects.filter(nome__startswith='Lean')
[<Artista: Artista object>, <Artista: Artista object>]

# Objetos que o nome inicie com “Lean” e o ano de nascimento seja inferior a 1982.
>>> Artista.objects.filter(nome__startswith='Lean',
                           data_nascimento__lt='1982-1-1')
# Objetos que o nome inicie com “Lean” e a data de nascimento seja superior ou igual a
# 20/06/1980.
>>> Artista.objects.filter(nome__startswith='Lean',
                           data_nascimento__gte='1980-6-20')
>>>Artista.objects.filter(nome__startswith='Lean').exclude(
                                                                                         31
                           data_nascimento__lt='1980-6-20')
Models

__exact (Uma comparação exata, case-sensitive)
>>> Artista.objects.get(nome__exact='Leandro')

Equivalente em SQL:
SELECT * FROM artista WHERE nome = 'Leandro';

✤ Quando não for informado um lookup, ou seja, o
argumento não possuir um duplo underscore, o tipo assumido
por padrão será o __exact.

  >>> Artista.objects.get(id__exact=4) # explícito
  >>> Artista.objects.get(id=4)        # __exact está implícito   32
Models

__iexact (Uma comparação exata, case-insensitive)
>>> Artista.objects.get(nome__iexact='leAndRo')

Equivalente em SQL:
SELECT * FROM artista WHERE LOWER(nome) = LOWER('leAndRo');

__contains | __icontains (Contendo uma string)
>>> Artista.objects.get(nome__contains='eand')

Equivalente em SQL:
SELECT * FROM artista WHERE nome LIKE '%eand%';               33
Models

__in (Sequência de elementos)
>>> Artista.objects.filter(id__in=(1,3,4))

Equivalente em SQL:
SELECT * FROM artista WHERE id IN (1, 3, 4);;

__startswith | __endswith (Inicie ou termine c/uma string)
>>> Artista.objects.filter(sobrenome__startswith='Zan')

Equivalente em SQL:
SELECT * FROM artista WHERE sobrenome LIKE 'Zan%';           34
Models

✤ Podemos ver um histórico dos SQLs que foram
executado pelo models na base de dados:
# Para visualizar a útima query executada.
>>> from django.db import connection
>>> Artista.objects.create(nome='Leandro',sobrenome='Zanuz',
                           data_nascimento=datetime(1970,8,25))
>>> print connection.queries[-1]['sql']
# Cache das últimas querys executadas.
>>> print connection.queries
# Gerando uma lista com valores específicos de uma query.
>>> Artista.objects.values_list('nome','sobrenome').filter(pk=1)
                                                                                35
✤ Não considere o LIMIT 21, é uma propriedade do método __repr__ da QuerySet.
Models

✤ Estes foram apenas alguns exemplos do uso
de lookups, para a referência completa acesse:
http://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups

✤ Relacionamento de objetos (JOINS).

# Seleciona os Albuns em que o nome do seu Artista inicie com “Lean”.
>>> Album.objects.filter(artista__nome__startswith='Lean')
# Seleciona os Albuns que o nome do seu Artista inicie com “Lean” e o sobrenome
# do Artista não seja NULO e o valor de venda do Album seja maior ou igual a 30.
>>> Album.objects.filter(artista__nome__startswith='Lean',
                         artista__sobrenome__isnull=False,
                         valor_venda__gte=30)                                      36
Models

✤ Nos exemplos até agora, utilizamos os filtros para
comparar valores do model com valores constantes,
por exemplo (__gte=30).
✤ Mas como fazemos para comparar valores de um
campo do model com outro campo do mesmo model?
✤ O django prove o objeto F() que permite realizar
comparações entre campos.
# Selecionar os Albuns que a descrição seja igual ao nome do Artista.
>>> from django.db.models import F
                                                                        37
>>> Album.objects.filter(descricao=F('artista__nome'))
Models

✤ Outros exemplos interessantes de QuerySets.
# Selecionando Artistas entre um intervalo de valores (BETWEEN).
>>> Artista.objects.filter(pk__gt=2,pk__lt=5)
# Seleciona os três primeiros objetos de uma QuerySet e após conta os objetos.
>>> Artista.objects.all()[:3].count()
# Seleciona até o décimo Artista, com passo dois (ou seja, de dois em dois).
>>> Artista.objects.all()[:10:2]
# Seleciona os Artistas que o nome contenha 'leandro' e ordene pelo
# sobrenome do Artista de forma decrescente.
>>> a = Artista.objects.filter(nome__icontains='leandro')
                               .order_by('sobrenome').reverse()
>>> print [(x.nome,x.sobrenome) for x in a]                                      38
Models

✤ QuerySet mais complexas, exemplo “AND e OR”.
# Exemplo utilizando cláusulas AND e OR.
>>> from django.db.models import Q
>>> Artista.objects.filter(Q(nome__istartswith='Lean'),
    Q(sobrenome__startswith='Zan')|Q(sobrenome__startswith='Ped'))

✤ Equivalente em SQL:
SELECT * FROM artista WHERE nome LIKE 'Lean%'
         AND (sobrenome LIKE 'Zan%' OR sobrenome LIKE 'Ped%')


                                                                     39
Models

✤ Excluindo objetos com models.
# Excluíndo um objeto.
>>> a = Artista.objects.get(pk=1)
>>> a.delete()
# Excluíndo todos os objetos cujo nome começe com 'Lean'.
>>> Artista.objects.filter(nome__istartswith='Lean').delete()
# Excluíndo todos os Artistas.
>>> Artista.objects.all().delete()

✤ Quando o django exclui um objeto, ele executa “ON DELETE
CASCADE”, ou seja, excluirá também qualquer objeto que
possua chave estrangeira apontando para o objeto a ser
                                                         40
excluído.
Models

✤ Atualizando objetos com models.
# Atualizando um objeto.
>>> a = Artista.objects.filter(pk=2)
>>> a.update(sobrenome='Santos')
# Atualizando o sobrenome de todos os objetos cujo nome seja João ou Fabrício.
>>> a = Artista.objects.filter(Q(nome__exact='João')|Q(nome__exact='Fabrício'))
>>> a.update(sobrenome='Santos')
>>> for x in a:
>>> x.save()

✤ Quando existir múltiplos elementos na Queryset o método
update não executa nenhum método save. Para salvar as alterações
                                                               41
deve-se executar o método save para cada elemento da QuerySet.
Models

✤ A função extra() permite alterar uma QuerySet
quando for necessário gerar um SQL de grande
complexidade e a sintaxe do django por si só não
oferece condições para tal.
✤ extra() é um hook para injetar cláusulas específicas
em um SQL gerado por uma QuerySet.
✤ Estes lookups “extras” talvez não sejam portáveis
entre diferentes bancos de dados (porque você está
escrevendo SQL explícito) e violando os princípios DRY,
você deve “esquecê-la” sempre que possível.          42
Models

✤ Manipulando QuerySets utilizando a função extra():
#Exemplo de utilização do extra, todos os artistas menos alguns específicos.
>>> Artista.objects.all().extra(where=['id NOT IN (3, 4, 5, 20)'])

#Fazendo um sub-select que calcula a media do preço de venda do Album por Artista.
>>> sub_select="SELECT AVG(valor_venda) FROM album AS ab
                WHERE ab.artista_id = album.artista_id"
>>> x = Album.objects.extra(select={'soma' : sub_select})
>>> x[0].soma

#Selecionando apenas os Artistas que já possuem Albuns cadastrados.
Artista.objects.extra(where=['EXISTS (SELECT 1 FROM album AS ab WHERE
ab.artista_id = artista.id)'])
                                                                                 43
Models

✤ Adicionando métodos próprios a objetos do models
para execução de tarefas específicas.
from django.core.urlresolvers import reverse
from datetime import datetime

class Artista(models.Model):
  …
  def get_absolute_url(self):
   return reverse("visualizar_artista",args=[self.id])
  def get_idade_artista(self):
   return datetime.now().year - self.data_nascimento.year
                                                            44
Models

✤ Ainda temos os relacionamentos One-to-one,
Many-to-one e Many-to-many que não abordados
neste treinamento básico.

✤  Documentação e exemplos completos para
estes tipos de relacionamentos estão disponí-
veis nos endereços web abaixo:
http://www.djangoproject.com/documentation/models/one_to_one/
http://www.djangoproject.com/documentation/models/many_to_one/
http://www.djangoproject.com/documentation/models/many_to_many/   45
URL dispatcher




                 46
URL dispatcher

✤ Utilizar URLs limpas e elegantes;

✤ Django permite que você defina as URLs da maneira
que quiser;
✤ Não são necessários .php, .cgi ou outras coisas sem o
menor sentido;
✤ URL (na forma de expressões regulares simples);

✤ Mapeamento das URLs pode ser tão extenso ou curto
quanto necessário.
                                                     47
URL dispatcher

✤ A seguir um exemplo de configuração das URLs.
from django.conf.urls.defaults import *

urlpatterns = patterns('musicos.views',
  (r'^artistas/$', 'listar_artistas'),
  url(r'^artista/(d+)/$', 'visualizar_artista',name="visualizar_artista"),
  (r'^albuns/$', 'listar_albuns'),
  (r'^album/(d+)/$', 'visualizar_album'),
  (r'^artista/(d+)/albuns/$', 'listar_albuns_artista'),
)

✤ Vamos adicionar no arquivo urls.py dentro da aplicação
musicos contendo estas URLs.                                                  48
URL dispatcher

✤ No urls.py do projeto teremos:
from django.conf.urls.defaults import *

urlpatterns = patterns('',
  (r'^', include('musicos.urls')),
)

✤ from django.conf.urls.defaults import * disponibiliza a
função patterns().
✤ Para capturarmos um valor da URL, simplesmente
colocamos parênteses em volta dele.
                                                       49
URL dispatcher

✤ Exemplos de requisição em                   django:
01 - http://127.0.0.1:8000/artistas/
02 - http://127.0.0.1:8000/artista/leandro/
03 - http://127.0.0.1:8000/artista/4/

✤ 01 - Corresponde ao primeiro elemento da lista de URLs, porque
os padrões são testados seguindo a ordem da lista. O django chama
a função listar_artistas(request).
✤ 02 - Não corresponde a nenhum padrão. O segundo elemento
da lista requer que para o artista seja informado somente dígitos.
✤ 03 - Corresponde ao segundo elemento da lista. O django chama
                                                              50
a função visualizar_artista(request, '4').
URL dispatcher

✤ Exemplo de             URL com grupos nomeados:
urlpatterns = patterns('musicos.views',
  (r'^artistas/(?P<codigo>d+)/$', 'visualizar_artista'),
)

✤ Utilizando desta forma, o django chamará a função
visualizar_artista(request, codigo='4'), ou seja, deverá passar os
parâmetros de forma nomeada e não mais posicional como
no exemplo anterior.

✤ Isso significa que a configuração das URLs está um pouco
mais explícita e menos propensa a bugs na ordem dos
argumentos.                                              51
URL dispatcher

✤ Como utilizar a função                          url():
Sintaxe: url(regex, view, kwargs=None, name=None, prefix='')
                                                   Prefixo da View
urlpatterns = patterns('musicos.views',
 url(r'^artistas/(?P<codigo>d{4})/$', 'visualizar_artista',name='visualizar_artista'), )
 {% url artista 4 %} → utilizando no template por exemplo

✤ Podemos utilizar a função url() no lugar de uma tupla, como um
argumento para patterns(). Isso é conveniente se você quer
especificar um nome a uma URL por exemplo.
✤ O parâmetro prefix tem o mesmo significado que o primeiro
argumento de patterns() e somente é relevante quando você está
                                                            52
passando uma string como um parâmetro para a view.
URL dispatcher

✤ Em qualquer ponto, seu urlpatterns pode "incluir" outros
módulos URLconf. Isso essencialmente "inclui" um conjunto
de URLs abaixo de outras:
from django.conf.urls.defaults import *
urlpatterns = patterns('',
  (r'^', include('musicos.urls')),
)

✤ Note que a expressão regular neste exemplo não possui um
$ (caractere que corresponde ao final de string), mas inclui uma /
(barra) no final. Isso porque o django deverá incluir as URLs
contidas neste arquivo de configuração adicional.               53
URL dispatcher

✤  O django também possui métodos utilitários
como o reverse() e o resolve() que facilitam o
manuseio das URLs. Veremos na seção views a
seguir um exemplo de suas utilizações.

✤  Referências e maiores informações sobre a
configuração das URLs em django podem ser
encontradas no endereço web abaixo:
http://docs.djangobrasil.org/topics/http/urls.html
                                                     54
Views




        55
Views

✤ Uma função view, ou somente view, é simples-
mente uma função python que recebe uma
requisição e retorna uma resposta web.

✤  Esta resposta pode ser um conteúdo HTML de
uma página, ou um redirecionamento, ou um
erro 404, ou um documento XML, uma imagem
ou qualquer outro conteúdo, como um arquivo
PDF por exemplo.
                                            56
Views

✤ Veja um exemplo simples de                  view.
from django.http import HttpResponse
import datetime

def listar_artistas(request):
  now = datetime.datetime.now()
  html = "<html><body>It is now %s.</body></html>" % now
  return HttpResponse(html)

✤ Vamos adicionar em nosso arquivo views.py dentro da
aplicação musicos esta função. Ela já possui uma URL
mapeada em particular, configurada no capítulo do URL
dispatcher.                                         57
Views

✤ Sub-classes do HttpResponse:
 from django.http import HttpResponse, HttpResponseNotFound
                                                                                        Exemplo de
 def funcao(request, codigo):                                                        utilização de uma
                                                                                     das sub-classe do
  ...                                                                                  HttpResponse
  if not artista:
      return HttpResponseNotFound('Artista não encontrado!')
  else:
      return HttpResponse(“%s %s”%(a.nome,a.sobrenome))
✤ Retornar códigos de erro HTTP no django é muito fácil. Existem
subclasses do HttpResponse para um número de códigos de status
comuns do HTTP além do 200 (que significa "OK"). Lista completa
de subclasses disponíveis na documentação:                   58
http://docs.djangobrasil.org/ref/request-response.html#ref-httpresponse-subclasses
Views

✤ Instanciando, manipulando e tratando exceções
de objetos do models através da view.
 from django.http import HttpResponse, HttpResponseNotFound
 from musicos.models import *

 def visualizar_artista(request,codigo):
   try:
      artista = Artista.objects.get(pk=codigo)
   except Artista.DoesNotExist:
      return HttpResponseNotFound('Artista %s inexistente!'%(codigo))
   return HttpResponse('%s %s' % (artista.nome,artista.sobrenome))

✤ http://127.0.0.1:8000/artista/2/ retorna o nome do Artista (2).       59
Templates




            60
Templates

✤ A linguagem de template do django foi desig-
nada para estabelecer um equilíbrio entre
facilidade e flexibilidade.

✤ Um template contém variáveis e tags, quando
o template é avaliado essas variáveis são
substituídas por valores.

✤ A seguir um modelo simples que ilustra um
template:                                   61
Templates
<html>
<head><title></title></head>
<body>
{% block conteudo %}                                           Exemplo
                                                       “listar_artistas.html”
<h1>{{ titulo }}</h1>                                      deverá estar na
{% for a in artistas %}                                   pasta “templates”
                                                         dentro da aplicação
   <div>                                                      “musicos”
      <a href="{{ a.get_absolute_url }}">
      {{ a.nome|upper }} : {{ a.get_idade_artista }}
      </a>
  </div>
{% endfor %}
{% endblock %}
</body>
                                                                                62
</html>
Templates

✤ Alterando a view listar_artistas para retornar o
novo template “listar_artistas.html” definido no
exemplo do anterior.
from django.shortcuts import render_to_response
from musicos.models import Artista
def listar_artistas(request):
 dc = dict(titulo="Lista de Artistas",
           artistas=Artista.objects.all())
 return render_to_response('listar_artistas.html',dc)

✤ Esta view já está disponível em nosso arquivo views.py
                                                        63
dentro da aplicação musicos.
Templates
✤ Para acessar o valor de uma variável em templates
utilizamos seu nome entre chaves: {{ variavel }}.
Quando um template encontra esta tag ele a avalia e a
substitui pelo valor da variável.
✤ Utiliza-se um ponto (.) para acessar atributos. No
exemplo, {{ artista.nome }} a tag será substituída pelo
atributo nome do objeto artista.
✤ Se for referenciada uma variável que não existe, o
template vai inserir o valor da configuração
TEMPLATE_STRING_IF_INVALID, que é '' (string vazia)
por padrão.                                      64
Templates

✤ Podemos modificar a apresentação dos valores de
variáveis utilizando filtros. A sintaxe dos filtros é
similar a: {{ nome|lower }}. Isso mostra o valor da
variável {{ nome }} após aplicado o filtro lower, que
converte o texto para minúsculas. Utiliza-se o pipe
(|) para aplicar filtros a variáveis.

✤ Filtros podem ser encadeados. A saída de um filtro
é aplicada ao próximo: {{ nome|escape|linebreaks }}.
                                                   65
Templates

✤ Alguns filtros possuem argumentos. A sintaxe de
um filtro que possui argumentos é similar a: {{ nome|
truncatewords:30 }}. Este filtro irá exibir somente as
primeiras 30 palavras da variável nome.

✤ Os argumentos de filtros que contem espaços
devem ser quoted (entre aspas) , por exemplo, para
inserir em uma lista espaços e virgulas use {{ lista|
join:", " }}.
http://docs.djangoproject.com/en/dev/ref/templates/builtins/   66
Templates

✤ A sintaxe de Tags é: {% tag %}. Tags são mais
complexas do que variáveis: Algumas criam texto na
saída, outras aplicam loops ou lógica.

✤ Algumas Tags requerem que se inicie e termine a
sua declaração: {% tag %} ...conteúdo... {% endtag %}.

✤ Comentários em templates são feitos utilizando a
sintaxe: {# …conteúdo... #}. Por exemplo, para comen-
tarmos uma váriável ou tag:
{{ variável }} → {# variável #} ou {% tag %} → {# tag #} 67
Templates

✤ Herança de Template: A mais poderosa – e a mais
complexa – parte da engine de templates do django. A
herança de template possibilita criar uma base
"esqueleto" que contem os elementos mais comuns de
um site e elementos de bloco que serão preenchidos
por conteúdos dinâmicos em certas regiões do
template.

✤ Porém não é difícil entender como a herança de
template funciona, vamos iniciar com um exemplo de
template "pai" denominado "base.html".           68
Templates
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <title>{% block titulo %}Meu Site{% endblock %}</title>
</head>
<body>
  <div id="menu">
                                                                Template
  {% block menu %}                                            “base.html”
    <ul>                                                     que deverá ser
                                                             extendido (pai).
       <li><a href="/">Página Inicial</a></li>
       <li><a href="/artistas/">Artistas</a></li>
    </ul>
  {% endblock %}
  </div>
  <div id="conteudo">
  {% block conteudo %}{% endblock %}
  </div>
</body>                                                                         69
</html>
Templates

✤ O template, no qual vamos denominamos base.html,
define um esqueleto HTML simples usado para gerar
uma página web.

✤ Agora será trabalho do template "filho" preencher
os blocos com conteúdo. No exemplo utilizado, a tag
{% block %} define três blocos no qual o template filho
poderá preencher.

✤ Todas as tags block dizem para o template filho que
essas partes de código podem ser sobrescritas.       70
Templates
{% extends "base.html" %}
{% block titulo %}Artistas do Site{% endblock %}
{% block conteudo %}                                          Template
                                                      “listar_artistas.html”
  {% for a in artistas %}                                (filho) que deverá
    <a href="{{ a.get_absolute_url }}">              estender do “base.html”.
    {{ a.nome|upper }} : {{ a.get_idade_artista }}
    </a><br/>
  {% endfor %}
{% endblock %}

✤ A tag {% extends %} é a chave. Ela diz para o template
se "estender" ao outro. Quando o sistema de template
avalia esse template, primeiro ele avalia o templase
base, no caso, "base.html".                        71
Templates

✤ Template Tags: Em resumo, template tag é uma
declaração (tag) em seu código HTML que executa uma
função python por trás da cortina. Esta função retorna
um trecho de código HTML, ou define um conjunto de
novas variáveis no contexto, permitindo que sejam
manipuladas ou exibidas conforme desejar.
✤ Primeiramente vamos adicionar uma nova pasta
denominada “templatetags” dentro da app musicos. E
vamos adicionar nesta pasta um arquivo “__init__.py”
vazio. Também vamos criar um arquivo “minhastags.py”
dentro da pasta templatetags, ou o nome que preferir. 72
Templates
from datetime import datetime
from django.template import Library,Node                  Template Tag que
from musicos.models import *                                imprime uma
                                                            mensagem de
                                                          “Feliz Aniversário”
register = Library()                                        para o Artista.

def exibe_mensagem_aniversario(parser, token):
   """Exibe o nome do Artista se estiver de Aniversário"""
   class aux(Node):
     def render(self, context):
        if context['a'].data_nascimento.strftime('%d-%m') == 
                       datetime.now().strftime('%d-%m'):
           return "Feliz Aniversário"
        return ""
   return aux()
register.tag('aniversario', exibe_mensagem_aniversario)                         73
Templates
{% extends "base.html" %}
                                                                     Adicionando a
{% load minhastags %}                                                 Template Tag
                                                                   {% aniversario %}
{% block titulo %}Artistas do Site{% endblock %}                    no template que
                                                                    lista os Artistas.
{% block conteudo %}
  {% for a in artistas %}
    <a href="{{ a.get_absolute_url }}">
    {{ a.nome|upper }} : {{ a.get_idade_artista }} {% aniversario %}
    </a><br/>
  {% endfor %}
{% endblock %}

✤ Será necessário carregar suas template tags customiza-
das no início do template {% load minhastags %} para que
seja possível incluí-las posteriormente em pontos
                                                       74
específicos do seu código HTML.
Middlewares




              75
Middlewares

✤ O Middleware é um framework de hook dentro do
processamento de uma requisição/resposta do django.
Ele é um sistema de “plugins”, leve e de baixo nível
para alterar globalmente valores de entrada ou saída.

✤ Cada middleware é responsável por fazer alguma
função específica. Por exemplo, o django inclui um
middleware, XViewMiddleware, que adiciona um
cabeçalho HTTP "X-View" a toda resposta para uma
requisição HEAD.
                                                   76
Middlewares

✤ Para ativar um novo middleware, adicione-o a lista
MIDDLEWARE_CLASSES no arquivo settings.py do
projeto.

MIDDLEWARE_CLASSES = (
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.middleware.doc.XViewMiddleware',
  …)

                                                              77
Middlewares

✤ Na requisição o django aplica os middlewares
process_request() e process_view() na ordem que
estão definidos no MIDDLEWARE_CLASSES, ou seja, de
cima para baixo.
✤ Na reposta, os middlewares process_response() e
process_exception() são aplicados na ordem inversa,
de baixo pra cima.
✤ Você pode imaginar como se fosse uma “cebola”,
onde cada classe middleware é uma "camada" que
envolve a view.                              78
Middlewares




              79
Middlewares
✤ process_request(self, request): É chamado em cada
request, antes do django decidir qual view executar.
Deve retornar None ou um objeto HttpResponse.
✤ process_view(self, request, view_func, view_args,
view_kwargs): É chamado logo após o django chamar a
view. Deve retornar None ou um objeto HttpResponse.
✤ Enquanto cada middleware retornar None, o django continuará
processando qualquer outro middleware da lista até executar a
view apropriada. Se algum middleware retornar um objeto
HttpResponse, o django não se incomodará em chamar
QUALQUER outra requisição, view ou exceção de middleware. Ele
                                                           80
retornará imediatamente o objeto HttpResponse.
Middlewares
✤ process_response(self, request, response): Diferen-
temente dos métodos process_request e process_view, o
método process_response() é sempre chamado, mesmo
que os métodos process_request e process_view da mesma
classe middleware foram pulados por causa de um
método de um middleware anterior que retornou um
HttpResponse. Este deve obrigatoriamente retornar um
objeto HttpResponse.
✤ process_exception(self, request, exception): O django
chama process_exception() quando uma view lança uma
exceção. O process_exception() deve retornar um None ou
                                                      81

um objeto HttpResponse.
Middlewares
✤ Exemplo de um middleware de redirecionamento:
from django.http HttpResponsePermanentRedirect
class RedirectMiddleware:
  def process_request(self, request):
    # etc...
    redirect_url = request.path+'?par1=1&par2=2'
    return HttpResponsePermanentRedirect(redirect_url)

Mais sobre middlewares:
http://docs.djangobrasil.org/topics/http/middleware.html
http://www.djangobook.com/en/beta/chapter16/               82
Forms
✤ O forms é uma poderosa biblioteca do django
para criação de formulários.
✤É possível gerar um formulário automatica-
mente através de um model;
✤  As técnicas de validação seguem o tipo do
campo, por exemplo, se for um EmailField, o
django verifica se o que foi digitado pelo usuário
é um endereço de e-mail válido;
http://docs.djangoproject.com/en/dev/ref/forms/fields/#built-in-field-classes   83
Forms




        84
Forms
✤ Adicionando duas novas URLs para cadastrar e
editar Artistas no urls.py da aplicação musicos:
url(r'^artista/novo/$', 'novo_artista', name="novo_artista"),
url(r'^artista/edita/(?P<codigo>d+)/$', 'edita_artista',
                                          name="edita_artista"),

✤ Existe mais de uma forma de trabalhar com django
forms. Vamos começar fazendo um form manualmente
para entender um pouco melhor a sua estrutura.
✤ A seguir vamos criar um arquivo forms.py dentro da
nossa aplicação musicos.                                           85
Forms
✤ Adicionando a classe FormArtista no arquivo forms.py.

from django import forms
class FormArtista(forms.Form):
  nome = forms.CharField(max_length=50)
  sobrenome = forms.CharField(max_length=50,required=False)
  data_nascimento = forms.DateField(
        widget=forms.widgets.DateInput(format="%m/%d/%Y"))

✤ Pode-se perceber no exemplo acima que a estrutura do
form FormArtista é muito similar a da classe models Artista.
                                                              86
http://docs.djangoproject.com/en/dev/ref/forms/fields/
Forms
✤ Vamos adicionar a view para manipular o novo form.
def novo_artista(request):                   from django.http import HttpResponseRedirect
                                             from django.core.urlresolvers import reverse
  if request.method == 'POST':               from django.core.context_processors import csrf
     form = FormArtista(request.POST)        from musicos.models import Artista,Album
                                             from musicos.forms import FormArtista
     dc = dict(form = form)
     if form.is_valid():
        a = Artista.objects.create(nome=form.cleaned_data['nome'],
                   sobrenome=form.cleaned_data['sobrenome'],
                   data_nascimento=form.cleaned_data['data_nascimento'])
        a.save()
        return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id]))
  else:
     dc = dict(form = FormArtista())
  dc.update(titulo='Novo Artista')
  dc.update(csrf(request))                                                                     87
  return render_to_response('form_artista.html',dc)
Forms
✤ Adicionamos um novo template “form_artista.html” na
pasta templates da aplicação musicos.
<html>
<head><title></title></head>
<body>
{% block conteudo %}
<h1>{{ titulo }}</h1>
<form method="post" action=".">
 {% csrf_token %}
 {{ form.as_p }}
 <input type="submit" value="cadastrar" />
</form>
{% endblock %}
                                                   88
</body></html>
Forms
✤ Finalizados os passos anteriores, deverá estar dispo-
nível o formulário para adicionarmos um novo Artista
através do nosso navegador web. Vamos acessar o
endereço:
http://127.0.0.1:8000/artista/novo/




                                                     89
Forms
✤ Quando já possuímos um modelo de dados definido
(models.py), podemos criar nossos formulários a partir
das classes do modelo existente.
✤ Vamos alterar a classe FormArtista no arquivo forms.py,
para que o nosso formulário agora seja criado a partir do
modelo de dados da classe Artista.
 from django.forms import ModelForm
 from musicos.models import Artista
 class FormArtista(ModelForm):
   class Meta:
      model = Artista
                                                                90
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/
Forms
✤ Agora podemos melhorar a implementação de nossa
view novo_artista. Quando os dados do formulário forem
válidos, podemos executar o metodo save() da instância
formulário, porque o mesmo contém uma Meta class de
Artista.

def novo_artista(request):
  …
     if form.is_valid():
        a = form.save()
     return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id]))
  …
                                                                                     91
http://www.slideshare.net/scorpion032/python-meta-classes-and-how-django-uses-them
Forms
# Cria uma instância do formulário com dados do POST.
form = FormArtista(request.POST)

# Grava um novo objeto Artista com os dados do formulário.
a = form.save()
a.id

# Cria um formulário para edição de um Artista.
a = Artista.objects.get(pk=codigo)
form = FormArtista(instance=a)

# Cria um formulário para editar um Artista utilizando o POST para popular o formulário.
a = Artista.objects.get(pk=codigo)
f = FormArtista(request.POST, instance=a)
f.save()                                                                                   92
Forms
✤ Vamos adicionar a view para alterar Artistas.
def edita_artista(request,codigo):
  if request.method == 'POST':
     form = FormArtista(request.POST)
     dc = dict(form = form)
     if form.is_valid():
        a = Artista.objects.get(pk=codigo)
        f = FormArtista(request.POST, instance=a)
        f.save()
        return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id]))
  else:
     dc = dict(form = FormArtista(instance=Artista.objects.get(pk=codigo)))
  dc.update(titulo='Edita Artista')
  dc.update(csrf(request))
                                                                                 93
  return render_to_response('form_artista.html',dc)
Forms
✤ Após incluída a view de edição, vamos acessar o
endereço conforme exemplo abaixo e alterar os dados de
um Artista, por exemplo, o id “14”.

http://127.0.0.1:8000/artista/edita/14/

✤ O django forms ainda oferece muito mais recursos para
explorar, os endereços web abaixo apresentam exemplos
e dicas bem interessantes para expandir seus conheci-
mentos.
http://docs.djangoproject.com/en/dev/ref/forms/fields/
http://docs.djangoproject.com/en/dev/topics/forms/modelforms/   94
O que mais?

✤ Alguns tópicos interessantes que não serão abor-
dados neste treinamento básico, mas seguem como
sugestão de pesquisa e complemento do aprendizado:

✤ Signals;          ✤ Authentication;
✤ FlatPages;        ✤ Internacionalization;
✤ URLs Slugs;       ✤ Sessions;
✤ Generic Views;    ✤ Testing;
✤ Caching;          ✤ Debbuging;

…e outros!                                       95
Bom trabalho!



                    Obrigado!
                Transforme o conhecimento em resultado!


Leandro Zanuz
Twitter: @leandrozanuz
E-mail: lzanuz@ucs.br
                                                          96

Más contenido relacionado

La actualidad más candente

Django para desenvolvimento web; porque ser repetitivo é chato.
Django para desenvolvimento web; porque ser repetitivo é chato.Django para desenvolvimento web; porque ser repetitivo é chato.
Django para desenvolvimento web; porque ser repetitivo é chato.Arthur Furlan
 
De Zero à Web com Python e Django
De Zero à Web com Python e DjangoDe Zero à Web com Python e Django
De Zero à Web com Python e DjangoOsvaldo Santana Neto
 
Boas práticas de django
Boas práticas de djangoBoas práticas de django
Boas práticas de djangoFilipe Ximenes
 
Django: desenvolvendo aplicações web de maneira simples e rápida!
Django: desenvolvendo aplicações web de maneira simples e rápida!Django: desenvolvendo aplicações web de maneira simples e rápida!
Django: desenvolvendo aplicações web de maneira simples e rápida!Felipe Queiroz
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN StackBruno Catão
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDaniel Paz
 
Desenvolvendo mvp com python
Desenvolvendo mvp com pythonDesenvolvendo mvp com python
Desenvolvendo mvp com pythonBruno Rocha
 
Cya grunt.js, hello gulp.js
Cya grunt.js, hello gulp.jsCya grunt.js, hello gulp.js
Cya grunt.js, hello gulp.jsMichael Douglas
 
Desenvolvimento web ágil com python e web2py
Desenvolvimento web ágil com python e web2pyDesenvolvimento web ágil com python e web2py
Desenvolvimento web ágil com python e web2pyRelsi Maron
 
Python e Django
Python e DjangoPython e Django
Python e Djangopugpe
 
PHP e AJAX: do Request ao Framework
PHP e AJAX: do Request ao FrameworkPHP e AJAX: do Request ao Framework
PHP e AJAX: do Request ao FrameworkRafael Dohms
 
PHPSP TestFest 2009
PHPSP TestFest 2009PHPSP TestFest 2009
PHPSP TestFest 2009Rafael Dohms
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1Thyago Maia
 
Django Tem Ritmo
Django Tem RitmoDjango Tem Ritmo
Django Tem Ritmoitalomaia
 

La actualidad más candente (20)

Django para desenvolvimento web; porque ser repetitivo é chato.
Django para desenvolvimento web; porque ser repetitivo é chato.Django para desenvolvimento web; porque ser repetitivo é chato.
Django para desenvolvimento web; porque ser repetitivo é chato.
 
Python na Web
Python na WebPython na Web
Python na Web
 
De Zero à Web com Python e Django
De Zero à Web com Python e DjangoDe Zero à Web com Python e Django
De Zero à Web com Python e Django
 
Boas práticas de django
Boas práticas de djangoBoas práticas de django
Boas práticas de django
 
Python 06
Python 06Python 06
Python 06
 
Django: desenvolvendo aplicações web de maneira simples e rápida!
Django: desenvolvendo aplicações web de maneira simples e rápida!Django: desenvolvendo aplicações web de maneira simples e rápida!
Django: desenvolvendo aplicações web de maneira simples e rápida!
 
Introdução à MEAN Stack
Introdução à MEAN StackIntrodução à MEAN Stack
Introdução à MEAN Stack
 
Desenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi BuilderDesenvolvimento de Módulos Divi Builder
Desenvolvimento de Módulos Divi Builder
 
Desenvolvendo mvp com python
Desenvolvendo mvp com pythonDesenvolvendo mvp com python
Desenvolvendo mvp com python
 
Python 07
Python 07Python 07
Python 07
 
Cya grunt.js, hello gulp.js
Cya grunt.js, hello gulp.jsCya grunt.js, hello gulp.js
Cya grunt.js, hello gulp.js
 
Desenvolvimento web ágil com python e web2py
Desenvolvimento web ágil com python e web2pyDesenvolvimento web ágil com python e web2py
Desenvolvimento web ágil com python e web2py
 
Javascript aula 01 - visão geral
Javascript   aula 01 - visão geralJavascript   aula 01 - visão geral
Javascript aula 01 - visão geral
 
Python e Django
Python e DjangoPython e Django
Python e Django
 
PHP e AJAX: do Request ao Framework
PHP e AJAX: do Request ao FrameworkPHP e AJAX: do Request ao Framework
PHP e AJAX: do Request ao Framework
 
PHPSP TestFest 2009
PHPSP TestFest 2009PHPSP TestFest 2009
PHPSP TestFest 2009
 
Mean Stack
Mean StackMean Stack
Mean Stack
 
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1
Desenvolvimento de Sistemas Web com PHP Frameworks - Aula 3 - 2019.1
 
Django Tem Ritmo
Django Tem RitmoDjango Tem Ritmo
Django Tem Ritmo
 
Aula javascript
Aula  javascriptAula  javascript
Aula javascript
 

Similar a Treinamento Básico de Django

Mini curso introdutório ao Django
Mini curso introdutório ao DjangoMini curso introdutório ao Django
Mini curso introdutório ao DjangoVinicius Mendes
 
Workshop Django Framework - 30/10/2018
Workshop Django Framework - 30/10/2018Workshop Django Framework - 30/10/2018
Workshop Django Framework - 30/10/2018Rafael Sales Pavarina
 
Introdução ao framework CodeIgniter
Introdução ao framework CodeIgniterIntrodução ao framework CodeIgniter
Introdução ao framework CodeIgniterAnderson Gonçalves
 
Documentação CakePHP - Português Br
Documentação CakePHP -  Português BrDocumentação CakePHP -  Português Br
Documentação CakePHP - Português BrLuiz Ladeira
 
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)Pedro Fernandes Vieira
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Alex Guido
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifaguestea329c
 
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...Dextra Sistemas / Etec Itu
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoFreedom DayMS
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1Sliedesharessbarbosa
 

Similar a Treinamento Básico de Django (20)

Django Módulo Básico Parte II
Django Módulo Básico Parte IIDjango Módulo Básico Parte II
Django Módulo Básico Parte II
 
Mini curso introdutório ao Django
Mini curso introdutório ao DjangoMini curso introdutório ao Django
Mini curso introdutório ao Django
 
Workshop Django Framework - 30/10/2018
Workshop Django Framework - 30/10/2018Workshop Django Framework - 30/10/2018
Workshop Django Framework - 30/10/2018
 
Django Básico
Django BásicoDjango Básico
Django Básico
 
Implementação de
Implementação de Implementação de
Implementação de
 
Aplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com DjangoAplicacoes Rapidas Para Web Com Django
Aplicacoes Rapidas Para Web Com Django
 
Introdução ao framework CodeIgniter
Introdução ao framework CodeIgniterIntrodução ao framework CodeIgniter
Introdução ao framework CodeIgniter
 
Documentação CakePHP - Português Br
Documentação CakePHP -  Português BrDocumentação CakePHP -  Português Br
Documentação CakePHP - Português Br
 
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)
Como desenvolver uma aplicação Web com django 2.2.13 (Parte 2 de 2)
 
Grails
GrailsGrails
Grails
 
Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.Desenvolvimento Ágil com Grails.
Desenvolvimento Ágil com Grails.
 
Crud
CrudCrud
Crud
 
ExtJS Jumpstart Parte 2
ExtJS Jumpstart Parte 2ExtJS Jumpstart Parte 2
ExtJS Jumpstart Parte 2
 
Cake Php
Cake PhpCake Php
Cake Php
 
ASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre TarifaASP.NET MVC - Alexandre Tarifa
ASP.NET MVC - Alexandre Tarifa
 
ASP.NET MVC
ASP.NET MVCASP.NET MVC
ASP.NET MVC
 
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...
VSSUMMIT 2023 - Como partir do zero e entregar uma API Profissional com .NET ...
 
Aplicações rápidas para a Web com Django
Aplicações rápidas para a Web com DjangoAplicações rápidas para a Web com Django
Aplicações rápidas para a Web com Django
 
JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
Mini curso de c#.net
Mini curso de c#.netMini curso de c#.net
Mini curso de c#.net
 

Treinamento Básico de Django

  • 1. django : Web Framework Treinamento Básico Entendendo django na prática! Leandro Zanuz Twitter: @leandrozanuz Setembro de 2010
  • 2. Cronograma ✤ Introdução; ✤ Criando e Configurando um Projeto; ✤ Models; ✤ URL Dispatcher; ✤ Views; ✤ Templates; ✤ Middlewares; ✤ Forms. 2
  • 3. O que é django ✤ Um framework web desenvolvido com a liguagem python; ✤ Adota o padrão MVC (Model-View-Controller); ✤ Ênfase em reusabilidade e plugabilidade; ✤ Desenvolvimento ágil; ✤ Baseado no conceito DRY (Don't Repeat Yourself); ✤ Mapeamento objeto-relacional ORM; ✤ Código aberto (open source). 3
  • 4. Arquitetura básica (MVC) 4 http://www.aprendendodjango.com/gallery/fluxo-no-mvc/file/
  • 5. O django-admin.py ✤ O django-admin.py deverá estar no “path” do sistema se você instalou o django via python setup.py. ✤ Se ele não estiver no path, você poderá encontrá-lo em site-packages/django/bin, onde site-packages é um diretório dentro da sua instalação do python. ✤ Considere a possibilidade de criar um link simbólico para o django-admin.py em algum lugar em seu path, como em /usr/local/bin. 5
  • 6. Criando o projeto ✤ Executando o comando a baixo, será criada a seguinte estrutura de arquivos do projeto: python django-admin.py startproject meusite __Init__.py : Arquivo de configuração para o python reconhecer a pasta do projeto como um pacote. manage.py : Script para execução de tarefas administrativas do projeto. settings.py : Configurações do projeto. urls.py : Configuração das URLs do projeto. 6
  • 7. Será que funciona? ✤ Vamos verificar se o projeto funciona. Vá para o diretório meusite, se você ainda não estiver nele, e rode o comando “python manage.py runserver 8000”. Você verá a seguinte saída na sua linha de comando: Validating models... 0 errors found Django version 1.3 pre-alpha SVN-13679, using settings 'meusite.settings' Development server is running at http://127.0.0.1:8000/ Quit the server with CONTROL-C. 7
  • 8. Testando no navegador ✤ Com o servidor rodando, visite http://127.0.0.1:8000/ com seu navegador Web. Você irá ver a página "Welcome to Django", em agradáveis tons de azul claro pastel. Ele funcionou! 8
  • 9. Anote e lembre-se ✤ Uma boa hora para ANOTAR: ✤ NÃO utilize este servidor em nada relacionado a um ambiente de produção. Este servidor tem como objetivo ser utilizado apenas durante o desen- volvimento. ✤ Django é um framework, não um servidor web! 9
  • 10. Banco de dados ✤ Vamos utilizar o banco de dados SQLite para este projeto. Caso o SQLite não esteja instalado, “sudo apt-get install sqlite3”. No arquivo settings.py do projeto vamos fazer as configurações necessárias: DATABASE_ENGINE = 'sqlite3' DATABASE_NAME = 'meusite.db' DATABASE_USER = '' DATABASE_PASSWORD = '' DATABASE_HOST = '' DATABASE_PORT = '' ✤ Aṕos salvar o arquivo execute “python manage.py syncdb”. LEMBRE-SE de anotar o usuário e a senha do super usuário. 10
  • 11. PySQLite ✤ Dica: Caso o python não possua o módulo do SQLite instalado “No module named _sqlite3”, você deverá instalar o pacote “sudo apt-get install python-sqlite” ou baixar PySQLite do site: http://code.google.com/p/pysqlite/ ✤ Se você fizer download módulo e estiver utilizando um ambiente Linux, será necessário instalar a lib “sudo apt-get install libsqlite3-dev” para compilar o módulo. 11
  • 12. Testando a base de dados ✤ Após configurar a base de dados, podemos verificar se a estrutura de tabelas está OK. .../meusite$ sqlite3 meusite.db SQLite version 3.7.2 Enter ".help" for instructions sqlite> .schema ✤ Você deverá ver diversas instruções “CREATE TABLE” referente as tabelas administrativas necessárias pelo framework. 12
  • 13. Criando uma aplicação ✤ Dentro da pasta meusite criada anteriormente, execute o comando a seguir. Será criada a seguinte estrutura de arquivos: python django-admin.py startapp musicos __Init__.py : Arquivo de configuração para o python reconhecer a pasta da aplicação como um pacote. models.py : Arquivo onde serão definidos os modelos. views.py : Arquivo que irá conter as views da aplicação. 13
  • 14. Adicionando a aplicação ✤ Vamos editar o settings.py novamente, alterar a linguagem para “pt-br” e adicionar a aplicação “musicos“ as apps instaladas. LANGUAGE_CODE = 'pt-br' .... INSTALLED_APPS = ( 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.sites', 'django.contrib.admin', 14 'musicos' )
  • 15. Models 15
  • 16. Models ✤ Camada de abstração do banco de dados; ✤ São classes que herdam de django.db.models. Model; ✤ Definem as entidades do sistema; ✤ Cada atributo de classe do modelo representa uma coluna do banco de dados. ✤ Já possui diversos tipos de colunas no banco de dados (ex: INTEGER, VARCHAR). 16
  • 17. Models from django.db import models class Artista(models.Model): nome = models.CharField(max_length=50, null=False) sobrenome = models.CharField(max_length=50) data_nascimento = models.DateField(null=False, db_column='data_de_nascimento') class Album(models.Model): artista = models.ForeignKey(Artista) descricao = models.CharField(max_length=100) data_lancamento = models.DateField() valor_venda = models.DecimalField(max_digits=5, decimal_places=2, null=False) http://docs.djangobrasil.org/ref/models/fields.html#common-model-field-options 17 http://docs.djangobrasil.org/howto/custom-model-fields.html#howto-custom-model-fields
  • 18. Models ✤ Cada tipo de campo recebe um certo conjunto de argumentos específicos. Por exemplo, CharField (e suas subclasses) requerem um argumento max_length que especifica o tamanho do campos VARCHAR que será usado para armazenar os dados. ✤ Há um conjunto de argumentos comuns disponí- veis para todos os tipos de campos. Todos são opcionais e são totalmente explicados na referência: http://docs.djangobrasil.org/ref/models/fields.html#common-model-field-options 18
  • 19. Models ✤ O metadado do model é "qualquer coisa que não seja um campo", assim como opções de ordenamento (attr: Options.ordering), nome de tabelas do banco de dados (db_table), ou nomes legíveis-por-humanos no singular ou plural (verbose_name_plural). ✤ Nenhum é obrigatório, e adicionar class Meta ao model é completamente opcional. class Meta: db_table='artista' 19 http://docs.djangobrasil.org/ref/models/options.html#ref-models-options
  • 20. Models ✤ Aṕos editar o arquivo models.py execute novamen- te “python manage.py syncdb”. Creating tables ... Creating table artista Creating table album Installing custom SQL ... Installing indexes ... No fixtures found. ✤ Note que neste momento as tabelas artista e album foram criadas. Agora vamos começar a manipular dados utilizando os modelos criados. 20
  • 21. Models ✤ Para utilizarmos o django ADMIN, vamos editar o arquivo urls.py que está na pasta do projeto e remover o comentário das linhas a seguir: # Remova o comentário das duas próximas linhas para ativar o admin: # from django.contrib import admin # admin.autodiscover() # Uncomment the next line to enable the admin: # (r'^admin/', include(admin.site.urls)), ✤ Localize estas linhas em seu arquivo urls.py e remova o comentário das linhas que possuem o # vermelho. 21
  • 22. Models ✤ Também editar o arquivo settings.py que está na pasta do projeto e remover o comentário da linha a seguir: INSTALLED_APPS = ( ... # Uncomment the next line to enable the admin: # 'django.contrib.admin', …) #Lembre-se de fazer a sincronização após adicionar uma nova app: >>> python manage.py syncdb ✤ Localize a propriedade INSTALLED_APPS e remova o 22 comentário da linha que possuem o # vermelho.
  • 23. Models ✤ Para conectar o modelo a interface administrativa, vamos criar o arquivo admin.py dentro da aplicação musicos para registrar os modelos que devem ser manipulados via ADMIN: from django.contrib import admin from models import Artista, Album admin.site.register(Artista) admin.site.register(Album) ✤ No arquivo admin.py são registrados os modelos que 23 podem ser manipulados pelo ADMIN.
  • 24. Models ✤ Para concluirmos a configuração básica do ADMIN, vamos editar novamente o arquivo models.py da aplicação musicos e adicionar uma descrição para cada classe do modelo: class Artista(models.Model): …. def __unicode__(self): return "%s %s" % (self.nome,self.sobrenome) class Album(models.Model): …. def __unicode__(self): return self.descricao 24
  • 25. Models ✤ Concluídas as alterações básicas necessárias, vamos testar o ADMIN. Aqui será necessário o usuário e a senha do superusuário definidas no syncbd. ✤ Acesse com seu navegador http://127.0.0.1:8000/admin/ 25
  • 26. Models ✤ Agora utilizaremos o comando “python manage.py shell“. O manage.py configura o ambiente do projeto para você. Vamos começar a trabalhar com models: # Import das classes do model que acabamos de criar. Vamos incluir >>> from musicos.models import Artista, Album diversos artistas para melhor ilustrar os exemplos # Não há nenhum registro nas tabelas ainda. a seguir. >>> Artista.objects.all() # Adicionando o primeiro Artista. >>> from datetime import datetime >>> a = Artista(nome='Leandro', sobrenome='zanuz', data_nascimento=datetime(1980,5,20)) >>> a.save() 26
  • 27. Models # Note que após salvar o objeto “a” ele passa a possuir um identificador (id). >>> a.id # Acessando atributos do objeto. >>> a.nome >>> a.sobrenome # Alterando dados do objeto Artista. >>> a.sobrenome = 'Zanuz' >>> a.save() # Selecionando um objeto Artista específico. >>> Artista.objects.get(id=1) ou (pk=1) # Listando todos os objetos Artista cadastrados. >>> Artista.objects.all() 27
  • 28. Models ✤ Para selecionar registros do banco de dados, você deverá construir uma QuerySet utilizando as classes do models. ✤ Uma QuerySet representa uma coleção de objetos de seu banco de dados. Ela pode conter zero, um ou muitos filtros (critérios que restringem a coleção baseado em argumentos fornecidos). ✤ Equivalente ao SQL, a QuerySet representa uma expressão SELECT, e os filtros são cláusulas limitadoras como o WHERE ou LIMIT. 28
  • 29. Models # Também podemos selecionando UM objeto pelo nome e/ou sobrenome. >>> a = Artista.objects.get(nome='Leandro',sobrenome='Zanuz') >>> a.id >>> a = Artista.objects.get(data_nascimento__year = 1980) >>> a.id ✤ Utilizando filtros em uma QuerySet: filter(**kwargs) Retorna uma nova QuerySet contendo somente os objetos que satisfazem os argumentos especificados. exclude(**kwargs) Retorna uma nova QuerySet contento somente os objetos que não 29 satisfazem os argumentos especificados.
  • 30. Models ✤ Para definir as cláusulas WHERE da QuerySet utilizamos os chamados “field lookups“, que são palavras chave específicas utilizadas nos métodos filter(), exclude() e get(). ✤ Como utilizar os lookups: field__lookuptype=value (__ é um duplo underscore). >>> Artista.objects.filter(data_nascimento__lte='1982-1-1') SELECT * FROM artista WHERE data_nascimento <= '1982-1-1'; 30 http://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups
  • 31. Models # Note que utilizando filtros não ocorre erro ao retornar MAIS DE UM objeto. >>> Artista.objects.filter(data_nascimento__year=1980) # Filtrando objetos que o nome inicie com “Lean”. >>> Artista.objects.filter(nome__startswith='Lean') [<Artista: Artista object>, <Artista: Artista object>] # Objetos que o nome inicie com “Lean” e o ano de nascimento seja inferior a 1982. >>> Artista.objects.filter(nome__startswith='Lean', data_nascimento__lt='1982-1-1') # Objetos que o nome inicie com “Lean” e a data de nascimento seja superior ou igual a # 20/06/1980. >>> Artista.objects.filter(nome__startswith='Lean', data_nascimento__gte='1980-6-20') >>>Artista.objects.filter(nome__startswith='Lean').exclude( 31 data_nascimento__lt='1980-6-20')
  • 32. Models __exact (Uma comparação exata, case-sensitive) >>> Artista.objects.get(nome__exact='Leandro') Equivalente em SQL: SELECT * FROM artista WHERE nome = 'Leandro'; ✤ Quando não for informado um lookup, ou seja, o argumento não possuir um duplo underscore, o tipo assumido por padrão será o __exact. >>> Artista.objects.get(id__exact=4) # explícito >>> Artista.objects.get(id=4) # __exact está implícito 32
  • 33. Models __iexact (Uma comparação exata, case-insensitive) >>> Artista.objects.get(nome__iexact='leAndRo') Equivalente em SQL: SELECT * FROM artista WHERE LOWER(nome) = LOWER('leAndRo'); __contains | __icontains (Contendo uma string) >>> Artista.objects.get(nome__contains='eand') Equivalente em SQL: SELECT * FROM artista WHERE nome LIKE '%eand%'; 33
  • 34. Models __in (Sequência de elementos) >>> Artista.objects.filter(id__in=(1,3,4)) Equivalente em SQL: SELECT * FROM artista WHERE id IN (1, 3, 4);; __startswith | __endswith (Inicie ou termine c/uma string) >>> Artista.objects.filter(sobrenome__startswith='Zan') Equivalente em SQL: SELECT * FROM artista WHERE sobrenome LIKE 'Zan%'; 34
  • 35. Models ✤ Podemos ver um histórico dos SQLs que foram executado pelo models na base de dados: # Para visualizar a útima query executada. >>> from django.db import connection >>> Artista.objects.create(nome='Leandro',sobrenome='Zanuz', data_nascimento=datetime(1970,8,25)) >>> print connection.queries[-1]['sql'] # Cache das últimas querys executadas. >>> print connection.queries # Gerando uma lista com valores específicos de uma query. >>> Artista.objects.values_list('nome','sobrenome').filter(pk=1) 35 ✤ Não considere o LIMIT 21, é uma propriedade do método __repr__ da QuerySet.
  • 36. Models ✤ Estes foram apenas alguns exemplos do uso de lookups, para a referência completa acesse: http://docs.djangoproject.com/en/dev/ref/models/querysets/#field-lookups ✤ Relacionamento de objetos (JOINS). # Seleciona os Albuns em que o nome do seu Artista inicie com “Lean”. >>> Album.objects.filter(artista__nome__startswith='Lean') # Seleciona os Albuns que o nome do seu Artista inicie com “Lean” e o sobrenome # do Artista não seja NULO e o valor de venda do Album seja maior ou igual a 30. >>> Album.objects.filter(artista__nome__startswith='Lean', artista__sobrenome__isnull=False, valor_venda__gte=30) 36
  • 37. Models ✤ Nos exemplos até agora, utilizamos os filtros para comparar valores do model com valores constantes, por exemplo (__gte=30). ✤ Mas como fazemos para comparar valores de um campo do model com outro campo do mesmo model? ✤ O django prove o objeto F() que permite realizar comparações entre campos. # Selecionar os Albuns que a descrição seja igual ao nome do Artista. >>> from django.db.models import F 37 >>> Album.objects.filter(descricao=F('artista__nome'))
  • 38. Models ✤ Outros exemplos interessantes de QuerySets. # Selecionando Artistas entre um intervalo de valores (BETWEEN). >>> Artista.objects.filter(pk__gt=2,pk__lt=5) # Seleciona os três primeiros objetos de uma QuerySet e após conta os objetos. >>> Artista.objects.all()[:3].count() # Seleciona até o décimo Artista, com passo dois (ou seja, de dois em dois). >>> Artista.objects.all()[:10:2] # Seleciona os Artistas que o nome contenha 'leandro' e ordene pelo # sobrenome do Artista de forma decrescente. >>> a = Artista.objects.filter(nome__icontains='leandro') .order_by('sobrenome').reverse() >>> print [(x.nome,x.sobrenome) for x in a] 38
  • 39. Models ✤ QuerySet mais complexas, exemplo “AND e OR”. # Exemplo utilizando cláusulas AND e OR. >>> from django.db.models import Q >>> Artista.objects.filter(Q(nome__istartswith='Lean'), Q(sobrenome__startswith='Zan')|Q(sobrenome__startswith='Ped')) ✤ Equivalente em SQL: SELECT * FROM artista WHERE nome LIKE 'Lean%' AND (sobrenome LIKE 'Zan%' OR sobrenome LIKE 'Ped%') 39
  • 40. Models ✤ Excluindo objetos com models. # Excluíndo um objeto. >>> a = Artista.objects.get(pk=1) >>> a.delete() # Excluíndo todos os objetos cujo nome começe com 'Lean'. >>> Artista.objects.filter(nome__istartswith='Lean').delete() # Excluíndo todos os Artistas. >>> Artista.objects.all().delete() ✤ Quando o django exclui um objeto, ele executa “ON DELETE CASCADE”, ou seja, excluirá também qualquer objeto que possua chave estrangeira apontando para o objeto a ser 40 excluído.
  • 41. Models ✤ Atualizando objetos com models. # Atualizando um objeto. >>> a = Artista.objects.filter(pk=2) >>> a.update(sobrenome='Santos') # Atualizando o sobrenome de todos os objetos cujo nome seja João ou Fabrício. >>> a = Artista.objects.filter(Q(nome__exact='João')|Q(nome__exact='Fabrício')) >>> a.update(sobrenome='Santos') >>> for x in a: >>> x.save() ✤ Quando existir múltiplos elementos na Queryset o método update não executa nenhum método save. Para salvar as alterações 41 deve-se executar o método save para cada elemento da QuerySet.
  • 42. Models ✤ A função extra() permite alterar uma QuerySet quando for necessário gerar um SQL de grande complexidade e a sintaxe do django por si só não oferece condições para tal. ✤ extra() é um hook para injetar cláusulas específicas em um SQL gerado por uma QuerySet. ✤ Estes lookups “extras” talvez não sejam portáveis entre diferentes bancos de dados (porque você está escrevendo SQL explícito) e violando os princípios DRY, você deve “esquecê-la” sempre que possível. 42
  • 43. Models ✤ Manipulando QuerySets utilizando a função extra(): #Exemplo de utilização do extra, todos os artistas menos alguns específicos. >>> Artista.objects.all().extra(where=['id NOT IN (3, 4, 5, 20)']) #Fazendo um sub-select que calcula a media do preço de venda do Album por Artista. >>> sub_select="SELECT AVG(valor_venda) FROM album AS ab WHERE ab.artista_id = album.artista_id" >>> x = Album.objects.extra(select={'soma' : sub_select}) >>> x[0].soma #Selecionando apenas os Artistas que já possuem Albuns cadastrados. Artista.objects.extra(where=['EXISTS (SELECT 1 FROM album AS ab WHERE ab.artista_id = artista.id)']) 43
  • 44. Models ✤ Adicionando métodos próprios a objetos do models para execução de tarefas específicas. from django.core.urlresolvers import reverse from datetime import datetime class Artista(models.Model): … def get_absolute_url(self): return reverse("visualizar_artista",args=[self.id]) def get_idade_artista(self): return datetime.now().year - self.data_nascimento.year 44
  • 45. Models ✤ Ainda temos os relacionamentos One-to-one, Many-to-one e Many-to-many que não abordados neste treinamento básico. ✤ Documentação e exemplos completos para estes tipos de relacionamentos estão disponí- veis nos endereços web abaixo: http://www.djangoproject.com/documentation/models/one_to_one/ http://www.djangoproject.com/documentation/models/many_to_one/ http://www.djangoproject.com/documentation/models/many_to_many/ 45
  • 47. URL dispatcher ✤ Utilizar URLs limpas e elegantes; ✤ Django permite que você defina as URLs da maneira que quiser; ✤ Não são necessários .php, .cgi ou outras coisas sem o menor sentido; ✤ URL (na forma de expressões regulares simples); ✤ Mapeamento das URLs pode ser tão extenso ou curto quanto necessário. 47
  • 48. URL dispatcher ✤ A seguir um exemplo de configuração das URLs. from django.conf.urls.defaults import * urlpatterns = patterns('musicos.views', (r'^artistas/$', 'listar_artistas'), url(r'^artista/(d+)/$', 'visualizar_artista',name="visualizar_artista"), (r'^albuns/$', 'listar_albuns'), (r'^album/(d+)/$', 'visualizar_album'), (r'^artista/(d+)/albuns/$', 'listar_albuns_artista'), ) ✤ Vamos adicionar no arquivo urls.py dentro da aplicação musicos contendo estas URLs. 48
  • 49. URL dispatcher ✤ No urls.py do projeto teremos: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^', include('musicos.urls')), ) ✤ from django.conf.urls.defaults import * disponibiliza a função patterns(). ✤ Para capturarmos um valor da URL, simplesmente colocamos parênteses em volta dele. 49
  • 50. URL dispatcher ✤ Exemplos de requisição em django: 01 - http://127.0.0.1:8000/artistas/ 02 - http://127.0.0.1:8000/artista/leandro/ 03 - http://127.0.0.1:8000/artista/4/ ✤ 01 - Corresponde ao primeiro elemento da lista de URLs, porque os padrões são testados seguindo a ordem da lista. O django chama a função listar_artistas(request). ✤ 02 - Não corresponde a nenhum padrão. O segundo elemento da lista requer que para o artista seja informado somente dígitos. ✤ 03 - Corresponde ao segundo elemento da lista. O django chama 50 a função visualizar_artista(request, '4').
  • 51. URL dispatcher ✤ Exemplo de URL com grupos nomeados: urlpatterns = patterns('musicos.views', (r'^artistas/(?P<codigo>d+)/$', 'visualizar_artista'), ) ✤ Utilizando desta forma, o django chamará a função visualizar_artista(request, codigo='4'), ou seja, deverá passar os parâmetros de forma nomeada e não mais posicional como no exemplo anterior. ✤ Isso significa que a configuração das URLs está um pouco mais explícita e menos propensa a bugs na ordem dos argumentos. 51
  • 52. URL dispatcher ✤ Como utilizar a função url(): Sintaxe: url(regex, view, kwargs=None, name=None, prefix='') Prefixo da View urlpatterns = patterns('musicos.views', url(r'^artistas/(?P<codigo>d{4})/$', 'visualizar_artista',name='visualizar_artista'), ) {% url artista 4 %} → utilizando no template por exemplo ✤ Podemos utilizar a função url() no lugar de uma tupla, como um argumento para patterns(). Isso é conveniente se você quer especificar um nome a uma URL por exemplo. ✤ O parâmetro prefix tem o mesmo significado que o primeiro argumento de patterns() e somente é relevante quando você está 52 passando uma string como um parâmetro para a view.
  • 53. URL dispatcher ✤ Em qualquer ponto, seu urlpatterns pode "incluir" outros módulos URLconf. Isso essencialmente "inclui" um conjunto de URLs abaixo de outras: from django.conf.urls.defaults import * urlpatterns = patterns('', (r'^', include('musicos.urls')), ) ✤ Note que a expressão regular neste exemplo não possui um $ (caractere que corresponde ao final de string), mas inclui uma / (barra) no final. Isso porque o django deverá incluir as URLs contidas neste arquivo de configuração adicional. 53
  • 54. URL dispatcher ✤ O django também possui métodos utilitários como o reverse() e o resolve() que facilitam o manuseio das URLs. Veremos na seção views a seguir um exemplo de suas utilizações. ✤ Referências e maiores informações sobre a configuração das URLs em django podem ser encontradas no endereço web abaixo: http://docs.djangobrasil.org/topics/http/urls.html 54
  • 55. Views 55
  • 56. Views ✤ Uma função view, ou somente view, é simples- mente uma função python que recebe uma requisição e retorna uma resposta web. ✤ Esta resposta pode ser um conteúdo HTML de uma página, ou um redirecionamento, ou um erro 404, ou um documento XML, uma imagem ou qualquer outro conteúdo, como um arquivo PDF por exemplo. 56
  • 57. Views ✤ Veja um exemplo simples de view. from django.http import HttpResponse import datetime def listar_artistas(request): now = datetime.datetime.now() html = "<html><body>It is now %s.</body></html>" % now return HttpResponse(html) ✤ Vamos adicionar em nosso arquivo views.py dentro da aplicação musicos esta função. Ela já possui uma URL mapeada em particular, configurada no capítulo do URL dispatcher. 57
  • 58. Views ✤ Sub-classes do HttpResponse: from django.http import HttpResponse, HttpResponseNotFound Exemplo de def funcao(request, codigo): utilização de uma das sub-classe do ... HttpResponse if not artista: return HttpResponseNotFound('Artista não encontrado!') else: return HttpResponse(“%s %s”%(a.nome,a.sobrenome)) ✤ Retornar códigos de erro HTTP no django é muito fácil. Existem subclasses do HttpResponse para um número de códigos de status comuns do HTTP além do 200 (que significa "OK"). Lista completa de subclasses disponíveis na documentação: 58 http://docs.djangobrasil.org/ref/request-response.html#ref-httpresponse-subclasses
  • 59. Views ✤ Instanciando, manipulando e tratando exceções de objetos do models através da view. from django.http import HttpResponse, HttpResponseNotFound from musicos.models import * def visualizar_artista(request,codigo): try: artista = Artista.objects.get(pk=codigo) except Artista.DoesNotExist: return HttpResponseNotFound('Artista %s inexistente!'%(codigo)) return HttpResponse('%s %s' % (artista.nome,artista.sobrenome)) ✤ http://127.0.0.1:8000/artista/2/ retorna o nome do Artista (2). 59
  • 60. Templates 60
  • 61. Templates ✤ A linguagem de template do django foi desig- nada para estabelecer um equilíbrio entre facilidade e flexibilidade. ✤ Um template contém variáveis e tags, quando o template é avaliado essas variáveis são substituídas por valores. ✤ A seguir um modelo simples que ilustra um template: 61
  • 62. Templates <html> <head><title></title></head> <body> {% block conteudo %} Exemplo “listar_artistas.html” <h1>{{ titulo }}</h1> deverá estar na {% for a in artistas %} pasta “templates” dentro da aplicação <div> “musicos” <a href="{{ a.get_absolute_url }}"> {{ a.nome|upper }} : {{ a.get_idade_artista }} </a> </div> {% endfor %} {% endblock %} </body> 62 </html>
  • 63. Templates ✤ Alterando a view listar_artistas para retornar o novo template “listar_artistas.html” definido no exemplo do anterior. from django.shortcuts import render_to_response from musicos.models import Artista def listar_artistas(request): dc = dict(titulo="Lista de Artistas", artistas=Artista.objects.all()) return render_to_response('listar_artistas.html',dc) ✤ Esta view já está disponível em nosso arquivo views.py 63 dentro da aplicação musicos.
  • 64. Templates ✤ Para acessar o valor de uma variável em templates utilizamos seu nome entre chaves: {{ variavel }}. Quando um template encontra esta tag ele a avalia e a substitui pelo valor da variável. ✤ Utiliza-se um ponto (.) para acessar atributos. No exemplo, {{ artista.nome }} a tag será substituída pelo atributo nome do objeto artista. ✤ Se for referenciada uma variável que não existe, o template vai inserir o valor da configuração TEMPLATE_STRING_IF_INVALID, que é '' (string vazia) por padrão. 64
  • 65. Templates ✤ Podemos modificar a apresentação dos valores de variáveis utilizando filtros. A sintaxe dos filtros é similar a: {{ nome|lower }}. Isso mostra o valor da variável {{ nome }} após aplicado o filtro lower, que converte o texto para minúsculas. Utiliza-se o pipe (|) para aplicar filtros a variáveis. ✤ Filtros podem ser encadeados. A saída de um filtro é aplicada ao próximo: {{ nome|escape|linebreaks }}. 65
  • 66. Templates ✤ Alguns filtros possuem argumentos. A sintaxe de um filtro que possui argumentos é similar a: {{ nome| truncatewords:30 }}. Este filtro irá exibir somente as primeiras 30 palavras da variável nome. ✤ Os argumentos de filtros que contem espaços devem ser quoted (entre aspas) , por exemplo, para inserir em uma lista espaços e virgulas use {{ lista| join:", " }}. http://docs.djangoproject.com/en/dev/ref/templates/builtins/ 66
  • 67. Templates ✤ A sintaxe de Tags é: {% tag %}. Tags são mais complexas do que variáveis: Algumas criam texto na saída, outras aplicam loops ou lógica. ✤ Algumas Tags requerem que se inicie e termine a sua declaração: {% tag %} ...conteúdo... {% endtag %}. ✤ Comentários em templates são feitos utilizando a sintaxe: {# …conteúdo... #}. Por exemplo, para comen- tarmos uma váriável ou tag: {{ variável }} → {# variável #} ou {% tag %} → {# tag #} 67
  • 68. Templates ✤ Herança de Template: A mais poderosa – e a mais complexa – parte da engine de templates do django. A herança de template possibilita criar uma base "esqueleto" que contem os elementos mais comuns de um site e elementos de bloco que serão preenchidos por conteúdos dinâmicos em certas regiões do template. ✤ Porém não é difícil entender como a herança de template funciona, vamos iniciar com um exemplo de template "pai" denominado "base.html". 68
  • 69. Templates <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> <head> <title>{% block titulo %}Meu Site{% endblock %}</title> </head> <body> <div id="menu"> Template {% block menu %} “base.html” <ul> que deverá ser extendido (pai). <li><a href="/">Página Inicial</a></li> <li><a href="/artistas/">Artistas</a></li> </ul> {% endblock %} </div> <div id="conteudo"> {% block conteudo %}{% endblock %} </div> </body> 69 </html>
  • 70. Templates ✤ O template, no qual vamos denominamos base.html, define um esqueleto HTML simples usado para gerar uma página web. ✤ Agora será trabalho do template "filho" preencher os blocos com conteúdo. No exemplo utilizado, a tag {% block %} define três blocos no qual o template filho poderá preencher. ✤ Todas as tags block dizem para o template filho que essas partes de código podem ser sobrescritas. 70
  • 71. Templates {% extends "base.html" %} {% block titulo %}Artistas do Site{% endblock %} {% block conteudo %} Template “listar_artistas.html” {% for a in artistas %} (filho) que deverá <a href="{{ a.get_absolute_url }}"> estender do “base.html”. {{ a.nome|upper }} : {{ a.get_idade_artista }} </a><br/> {% endfor %} {% endblock %} ✤ A tag {% extends %} é a chave. Ela diz para o template se "estender" ao outro. Quando o sistema de template avalia esse template, primeiro ele avalia o templase base, no caso, "base.html". 71
  • 72. Templates ✤ Template Tags: Em resumo, template tag é uma declaração (tag) em seu código HTML que executa uma função python por trás da cortina. Esta função retorna um trecho de código HTML, ou define um conjunto de novas variáveis no contexto, permitindo que sejam manipuladas ou exibidas conforme desejar. ✤ Primeiramente vamos adicionar uma nova pasta denominada “templatetags” dentro da app musicos. E vamos adicionar nesta pasta um arquivo “__init__.py” vazio. Também vamos criar um arquivo “minhastags.py” dentro da pasta templatetags, ou o nome que preferir. 72
  • 73. Templates from datetime import datetime from django.template import Library,Node Template Tag que from musicos.models import * imprime uma mensagem de “Feliz Aniversário” register = Library() para o Artista. def exibe_mensagem_aniversario(parser, token): """Exibe o nome do Artista se estiver de Aniversário""" class aux(Node): def render(self, context): if context['a'].data_nascimento.strftime('%d-%m') == datetime.now().strftime('%d-%m'): return "Feliz Aniversário" return "" return aux() register.tag('aniversario', exibe_mensagem_aniversario) 73
  • 74. Templates {% extends "base.html" %} Adicionando a {% load minhastags %} Template Tag {% aniversario %} {% block titulo %}Artistas do Site{% endblock %} no template que lista os Artistas. {% block conteudo %} {% for a in artistas %} <a href="{{ a.get_absolute_url }}"> {{ a.nome|upper }} : {{ a.get_idade_artista }} {% aniversario %} </a><br/> {% endfor %} {% endblock %} ✤ Será necessário carregar suas template tags customiza- das no início do template {% load minhastags %} para que seja possível incluí-las posteriormente em pontos 74 específicos do seu código HTML.
  • 76. Middlewares ✤ O Middleware é um framework de hook dentro do processamento de uma requisição/resposta do django. Ele é um sistema de “plugins”, leve e de baixo nível para alterar globalmente valores de entrada ou saída. ✤ Cada middleware é responsável por fazer alguma função específica. Por exemplo, o django inclui um middleware, XViewMiddleware, que adiciona um cabeçalho HTTP "X-View" a toda resposta para uma requisição HEAD. 76
  • 77. Middlewares ✤ Para ativar um novo middleware, adicione-o a lista MIDDLEWARE_CLASSES no arquivo settings.py do projeto. MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.middleware.doc.XViewMiddleware', …) 77
  • 78. Middlewares ✤ Na requisição o django aplica os middlewares process_request() e process_view() na ordem que estão definidos no MIDDLEWARE_CLASSES, ou seja, de cima para baixo. ✤ Na reposta, os middlewares process_response() e process_exception() são aplicados na ordem inversa, de baixo pra cima. ✤ Você pode imaginar como se fosse uma “cebola”, onde cada classe middleware é uma "camada" que envolve a view. 78
  • 80. Middlewares ✤ process_request(self, request): É chamado em cada request, antes do django decidir qual view executar. Deve retornar None ou um objeto HttpResponse. ✤ process_view(self, request, view_func, view_args, view_kwargs): É chamado logo após o django chamar a view. Deve retornar None ou um objeto HttpResponse. ✤ Enquanto cada middleware retornar None, o django continuará processando qualquer outro middleware da lista até executar a view apropriada. Se algum middleware retornar um objeto HttpResponse, o django não se incomodará em chamar QUALQUER outra requisição, view ou exceção de middleware. Ele 80 retornará imediatamente o objeto HttpResponse.
  • 81. Middlewares ✤ process_response(self, request, response): Diferen- temente dos métodos process_request e process_view, o método process_response() é sempre chamado, mesmo que os métodos process_request e process_view da mesma classe middleware foram pulados por causa de um método de um middleware anterior que retornou um HttpResponse. Este deve obrigatoriamente retornar um objeto HttpResponse. ✤ process_exception(self, request, exception): O django chama process_exception() quando uma view lança uma exceção. O process_exception() deve retornar um None ou 81 um objeto HttpResponse.
  • 82. Middlewares ✤ Exemplo de um middleware de redirecionamento: from django.http HttpResponsePermanentRedirect class RedirectMiddleware: def process_request(self, request): # etc... redirect_url = request.path+'?par1=1&par2=2' return HttpResponsePermanentRedirect(redirect_url) Mais sobre middlewares: http://docs.djangobrasil.org/topics/http/middleware.html http://www.djangobook.com/en/beta/chapter16/ 82
  • 83. Forms ✤ O forms é uma poderosa biblioteca do django para criação de formulários. ✤É possível gerar um formulário automatica- mente através de um model; ✤ As técnicas de validação seguem o tipo do campo, por exemplo, se for um EmailField, o django verifica se o que foi digitado pelo usuário é um endereço de e-mail válido; http://docs.djangoproject.com/en/dev/ref/forms/fields/#built-in-field-classes 83
  • 84. Forms 84
  • 85. Forms ✤ Adicionando duas novas URLs para cadastrar e editar Artistas no urls.py da aplicação musicos: url(r'^artista/novo/$', 'novo_artista', name="novo_artista"), url(r'^artista/edita/(?P<codigo>d+)/$', 'edita_artista', name="edita_artista"), ✤ Existe mais de uma forma de trabalhar com django forms. Vamos começar fazendo um form manualmente para entender um pouco melhor a sua estrutura. ✤ A seguir vamos criar um arquivo forms.py dentro da nossa aplicação musicos. 85
  • 86. Forms ✤ Adicionando a classe FormArtista no arquivo forms.py. from django import forms class FormArtista(forms.Form): nome = forms.CharField(max_length=50) sobrenome = forms.CharField(max_length=50,required=False) data_nascimento = forms.DateField( widget=forms.widgets.DateInput(format="%m/%d/%Y")) ✤ Pode-se perceber no exemplo acima que a estrutura do form FormArtista é muito similar a da classe models Artista. 86 http://docs.djangoproject.com/en/dev/ref/forms/fields/
  • 87. Forms ✤ Vamos adicionar a view para manipular o novo form. def novo_artista(request): from django.http import HttpResponseRedirect from django.core.urlresolvers import reverse if request.method == 'POST': from django.core.context_processors import csrf form = FormArtista(request.POST) from musicos.models import Artista,Album from musicos.forms import FormArtista dc = dict(form = form) if form.is_valid(): a = Artista.objects.create(nome=form.cleaned_data['nome'], sobrenome=form.cleaned_data['sobrenome'], data_nascimento=form.cleaned_data['data_nascimento']) a.save() return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id])) else: dc = dict(form = FormArtista()) dc.update(titulo='Novo Artista') dc.update(csrf(request)) 87 return render_to_response('form_artista.html',dc)
  • 88. Forms ✤ Adicionamos um novo template “form_artista.html” na pasta templates da aplicação musicos. <html> <head><title></title></head> <body> {% block conteudo %} <h1>{{ titulo }}</h1> <form method="post" action="."> {% csrf_token %} {{ form.as_p }} <input type="submit" value="cadastrar" /> </form> {% endblock %} 88 </body></html>
  • 89. Forms ✤ Finalizados os passos anteriores, deverá estar dispo- nível o formulário para adicionarmos um novo Artista através do nosso navegador web. Vamos acessar o endereço: http://127.0.0.1:8000/artista/novo/ 89
  • 90. Forms ✤ Quando já possuímos um modelo de dados definido (models.py), podemos criar nossos formulários a partir das classes do modelo existente. ✤ Vamos alterar a classe FormArtista no arquivo forms.py, para que o nosso formulário agora seja criado a partir do modelo de dados da classe Artista. from django.forms import ModelForm from musicos.models import Artista class FormArtista(ModelForm): class Meta: model = Artista 90 http://docs.djangoproject.com/en/dev/topics/forms/modelforms/
  • 91. Forms ✤ Agora podemos melhorar a implementação de nossa view novo_artista. Quando os dados do formulário forem válidos, podemos executar o metodo save() da instância formulário, porque o mesmo contém uma Meta class de Artista. def novo_artista(request): … if form.is_valid(): a = form.save() return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id])) … 91 http://www.slideshare.net/scorpion032/python-meta-classes-and-how-django-uses-them
  • 92. Forms # Cria uma instância do formulário com dados do POST. form = FormArtista(request.POST) # Grava um novo objeto Artista com os dados do formulário. a = form.save() a.id # Cria um formulário para edição de um Artista. a = Artista.objects.get(pk=codigo) form = FormArtista(instance=a) # Cria um formulário para editar um Artista utilizando o POST para popular o formulário. a = Artista.objects.get(pk=codigo) f = FormArtista(request.POST, instance=a) f.save() 92
  • 93. Forms ✤ Vamos adicionar a view para alterar Artistas. def edita_artista(request,codigo): if request.method == 'POST': form = FormArtista(request.POST) dc = dict(form = form) if form.is_valid(): a = Artista.objects.get(pk=codigo) f = FormArtista(request.POST, instance=a) f.save() return HttpResponseRedirect(reverse("visualizar_artista",args=[a.id])) else: dc = dict(form = FormArtista(instance=Artista.objects.get(pk=codigo))) dc.update(titulo='Edita Artista') dc.update(csrf(request)) 93 return render_to_response('form_artista.html',dc)
  • 94. Forms ✤ Após incluída a view de edição, vamos acessar o endereço conforme exemplo abaixo e alterar os dados de um Artista, por exemplo, o id “14”. http://127.0.0.1:8000/artista/edita/14/ ✤ O django forms ainda oferece muito mais recursos para explorar, os endereços web abaixo apresentam exemplos e dicas bem interessantes para expandir seus conheci- mentos. http://docs.djangoproject.com/en/dev/ref/forms/fields/ http://docs.djangoproject.com/en/dev/topics/forms/modelforms/ 94
  • 95. O que mais? ✤ Alguns tópicos interessantes que não serão abor- dados neste treinamento básico, mas seguem como sugestão de pesquisa e complemento do aprendizado: ✤ Signals; ✤ Authentication; ✤ FlatPages; ✤ Internacionalization; ✤ URLs Slugs; ✤ Sessions; ✤ Generic Views; ✤ Testing; ✤ Caching; ✤ Debbuging; …e outros! 95
  • 96. Bom trabalho! Obrigado! Transforme o conhecimento em resultado! Leandro Zanuz Twitter: @leandrozanuz E-mail: lzanuz@ucs.br 96