Buscar

Introdução ao Django

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 121 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 6, do total de 121 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 9, do total de 121 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

Apresentando
Marcel P. Caraciolo
@marcelcaraciolo
Residência RISE - 2011
1
Esta palestra está sobre a licença Creative Commons
Residência de Reuso - 2011.1 - Recife/PE
ou seja distribuir , modificar e copiar tudo liberado :D
mas sempre cite a original nos seus créditos 
http://creativecommons.org/licenses/by-sa/3.0/
Esta aula faz parte do curso de Residência de Reuso de Software pela RISE
2
O que é Django ?
Residência de Reuso - 2011.1 - Recife/PE
3
O que é Django ?
Não é Jungle. É Django.
4
Não é Django Reinhardt ... na verdade é
5
É um framework web
Criado em 2005
Lawrence, Kansas -
 Lawerence Journal World
Licença BSD
Aplicação Web
Residência de Reuso - 2011.1 - Recife/PE
6
É um framework web
Criado em 2005
Lawrence, Kansas -
 Lawerence Journal World
Licença BSD
Aplicação Web
http://www.flickr.com/photos/plinton/215437652/
DRY
Don’t Repeat Yourself
7
Django é Python!
Escrito em Python
Focado em 
Desenvolvimento Ágil
Don’t Repeat yourself
!"#$%&'()*"*
! *+"(,%-'./0.
!"#$$$%&'(&)*+,
Residência de Reuso - 2011.1 - Recife/PE
8
Projeto == Várias aplicações
http://djangopackages.com
django.contrib.admin
django.contrib.commentssouth
django-paginationdjango-mailer
django-registration
...
Residência de Reuso - 2011.1 - Recife/PE
9
E isto é MVC ?
Models
Controllers Views
Residência de Reuso - 2011.1 - Recife/PE
10
Alguns chamam de MTV
Residência de Reuso - 2011.1 - Recife/PE
11
Alguns chamam de MTV
Model - Template - Views
12
Aplicações
Deve fazer uma coisa, e fazer direito
Se a descrição de sua aplicação for maior que uma
linha, talvez ela precise ser quebrada
Reutilizável (DRY se lembra ?)
Talvez já exista!
Residência de Reuso - 2011.1 - Recife/PE
13
Instalando a aplicação
Aplicações
Coloque no path (PYTHONPATH)
Coloque no INSTALLED_APPS no settings.py 
settings.py
Residência de Reuso - 2011.1 - Recife/PE
14
Aplicações
A aplicação é auto-contida
tests.py
urls.py
templates/
admin.py
Residência de Reuso - 2011.1 - Recife/PE
15
Fácil de Usar
$ pip install django
$ django-admin.py startproject dwitter
Residência de Reuso - 2011.1 - Recife/PE
16
Fácil de Usar
$ pip install django
$ django-admin.py startproject dwitter
!"#$"%&'#()"*%+"*,#-)*
$ django-admin.py startproject dwitter
!"#$%&'"(%")*"+,'-(.&'///"0"%%./%*(%0#%1/%2#3#444
 __init__.py
 manage.py 
 settings.py 
 urls.py
!".51"23%+'*(4'%"2(")*"+,'-(.&'"5!"#$%&#'(6"(*"278*9'/
6#%7%8-9#"*(%:;<
Residência de Reuso - 2011.1 - Recife/PE
17
Fácil de Usar
$ cd dwitter
$ python manage.py runserver!""#$%#"&$'()*"+&,"+-(%*+
.(&/&0%1("+)&234
$ cd dwitter
$ python manage.py runserver
Validating models...
0 errors found
Django version 1.1, using settings 'dwitter.settings'
Development server is running at http://
127.0.0.1:8000/
Quit the server with CONTROL-C.
Já vem com um servidor web !
Residência de Reuso - 2011.1 - Recife/PE
18
Fácil de Usar
Residência de Reuso - 2011.1 - Recife/PE
19
Quem usa ?
!"#$$$
!"#$%&'#()'*+)&,-.
Residência de Reuso - 2011.1 - Recife/PE
20
Documentação
21
Banco de Dados
!"#$%
22
Banco de Dados!"#$%&'()*+
def book_list(request):
 try:
 db = MySQLdb.connect(user='me', db='mydb',
 passwd='secret', host='localhost')
 cursor = db.cursor()
 cursor.execute('SELECT nama FROM books ORDER BY name')
 names = []
 for row in cursor.fetchall()
 names.append(row[0])
 db.close()
 except:
 return render_to_response('500.html')
 return render_to_response('book_list.html', {'names':names})
Residência de Reuso - 2011.1 - Recife/PE
23
Banco de Dados
!"#$%&'()#*'#!"#$%&+++#,-,
12 linhas em Python ... :(
24
Banco de Dados
12 linhas em Python ... :(
!"#$%!&'()*+"(,-./0-,$1-223045
25
ORM
Padrão Active Record
Classe Table
!"#$%&'()*+
def book_list(request):
 names = Books.objects.all().order_by('name')
 return render_to_response('book_list.html', {'names':names})
Residência de Reuso - 2011.1 - Recife/PE
26
Criar tabelas?! Fácil!
$ python manage.py syncdb
Crie as tabelas no banco. E pronto!
Residência de Reuso - 2011.1 - Recife/PE
27
Vamos começar ?
djangoproject.com - site oficial
djangobrasil.org - site oficial nacional
djangogigs.com - vagas de empregro
djangopeople.net - rede social
djangosites.org - rede social de sites em django
djangosearch.com - busca assuntos relacionados
djangocodesearch.com - busca nos fontes
Residência de Reuso - 2011.1 - Recife/PE
28
Vamos à prática!
Residência de Reuso - 2011.1 - Recife/PE
29
Instalação Python
http://www.python.org/download
sudo apt-get install python
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'()(*+,%#-.'/0%
$ sudo apt-get install python
http://www.python.org/download/
!"#$%&'#()*+%,"-./0'%.)1%2'*1,#"'1%2.5.4%0%2.6.1
!"#$%&'()(*+,%#-.'/0%
$ sudo apt-get install python
http://www.python.org/download/
!"#$%&'#()*+%,"-./0'%.)1%2'*1,#"'1%2.5.4%0%2.6.1
!"#$%&'()(*+,%#-.'/0%
$ sudo apt-get install python
http://www.python.org/download/
!"#$%&'#()*+%,"-./0'%.)1%2'*1,#"'1%2.5.4%0%2.6.1Já vem com python instalado
30
Instalação de Banco de Dados
Poderíamos escolher dentre vários SGBD’s
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'(')&#)*"+"'),-).(/-),-)0(+"/1
2)3$45(6-/1)
2)7"/+%'-89:
2);<89:
2)3'(46-
2)!"#$%&
2)!"*&#5,(,1)
2)8<=(/-)89:)>#<?@-'-
2)A.;)0.B
2);54'"/"C)89:)8-'D-')BEEF
2)G5'-=5',
2)30.!
'()*+,%-.-/$0+)!123
31
Instalação de Banco de Dados
Vamos usar o Sqlite!
Residência de Reuso - 2011.1 - Recife/PE
Precisa instalar ?! Não :D
Python já vem com SGBD incluso! 
http://docs.python.org/library/sqlite3.html
32
Instalação de Django
3 maneiras!
Residência de Reuso - 2011.1 - Recife/PE
apt-get install python-django
http://www.djangoproject.com/download
python setup.py install
http://www.djangoproject.com/svn/django/trunk
33
Instalação de Django
Residência de Reuso - 2011.1 - Recife/PE
!""#$%&'()
>>> import django
>>> django.VERSION
(1, 1, 0, 'final', 0)
>>> import django
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ImportError: No module named django
!""#$%&'()
>>> import django
>>> django.VERSION
(1, 1, 0, 'final', 0)
>>> import django
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ImportError: No module named django
!""#$%&'()
>>> import django
>>> django.VERSION
(1, 1, 0, 'final', 0)
>>> import django
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ImportError: No module named django
!""#$%&'()
>>> import django
>>> django.VERSION
(1, 1, 0, 'final', 0)
>>> import django
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
ImportError: No module named django
34
Criando um projeto
Residência de Reuso - 2011.1 - Recife/PE
!"#$"%&'#()"*%+"*,#-)*
$ django-admin.py startproject dwitter
!"#$%&'"(%")*"+,'-(.&'///"0"%%./%*(%0#%1/%2#3#444
 __init__.py
 manage.py 
 settings.py 
 urls.py
5#%6%7-8#"*(%9:;
$ django-admin.py startproject seminario
35
Criando um projeto
Residência de Reuso - 2011.1 - Recife/PE!"#$%!&'(
36
Criando um projeto
Residência de Reuso - 2011.1 - Recife/PE
!""#$%#"&$'()*"+&,"+-(%*+
.(&/&0%1("+)&234$ cd dwitter
$ python manage.py runserver
Validating models...
0 errors found
Django version 1.1, using settings 'dwitter.settings'
Development server is running at http://
127.0.0.1:8000/
Quit the server with CONTROL-C.
37
Entendendo sua App
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&$'()&*+
!!"#$!%&%!+,%- "'()*%&%.%/0-)1% #!+),!$*"!,%&%234-"5%6
38
urls.py
Residência de Reuso - 2011.1 - Recife/PE
Módulo urls.py serve como porta de entrada para requisições HTTP
As URL’s são definidas por expressões regulares que redirecionam as 
requisições para as respectivas views 
!"#$%&%'($)*$
! "#$%&'()*$+,-$./&$+&,-+$&*.*$/0(),+$1($(2,)+1+$/+)+$#+3$
/(4&5*2(3$6778
! 9($1(%2(2$:;<3$(#(=+2,(3$.(15+2,($(>/)(35*2(3$)(=0#+)(3$
?0($)(15)5=(2$+$@02&5*2(3$1($0(12$./&
0)#3A/B
C5(D3A/B
'E/FGG.B35,(A&*.G+H*0,G
',.# ...
I0)#/+E()23J
39
views.py
Residência de Reuso - 2011.1 - Recife/PE
Módulo views.py tem funções com parâmetros um objeto HttpRequest
Retorna um objeto HttpResponse
!"#$%&%'($)*$
! "#$%&'()*'$+,$-),./012$3,()4,$(565$1#376,835/$&'$549,85$
+,-"./0.$)$2$85+5/$:5/$1#376,835/$+,$:#$;<"$(#18&3#+5/=$
8,'),'+5$>&,$+,-5:-,3$/),613,$&'$549,85$+,-".$-12$.
-),./012
+,-"./0.$)345%666
+,-".$-12$.34
40
Exemplo
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&%'($)*$
+,-./01%2!""http://mysite.com/time
from django.conf.urls.defaults import *
from mysite.views import hora_actual
urlpatterns = patterns('',
 (r'^time/$', hora_actual),
)
from django.http import HttpResponse
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 html = "Son las %s." % now
 return HttpResponse(html)
!"#$%&'
()*+$%&'
urls.py
!"#$%&%'($)*$
+,-./01%2!""http://mysite.com/time
from django.conf.urls.defaults import *
from mysite.views import hora_actual
urlpatterns = patterns('',
 (r'^time/$', hora_actual),
)
from django.http import HttpResponse
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 html = "Son las %s." % now
 return HttpResponse(html)
!"#$%&'
()*+$%&'views.py
http://mysite.com.time
41
Exemplo 2
Residência de Reuso - 2011.1 - Recife/PE
urls.py
views.py
http://mysite.com.time/plus/2
!"#$%&%'($)*$
from django.conf.urls.defaults import *
from mysite.views import dentro_de
urlpatterns = patterns('',
 (r'^time/plus/(\d{1,2})/$', dentro_de),
)
from django.http import HttpResponse
from datetime import datetime, timedelta
def dentro_de(request, offset):
 offset = int(offset)
 dt = datetime.now() + timedelta(hours=offset)
 html = "En %i hora(s), serán las %s." % (offset, dt)
 return HttpResponse(html)
!"#$%&'
()*+$%&'
+,-./01%2!""http://mysite.com/time/plus/2
!"#$%&%'($)*$
from django.conf.urls.defaults import *
from mysite.views import dentro_de
urlpatterns = patterns('',
 (r'^time/plus/(\d{1,2})/$', dentro_de),
)
from django.http import HttpResponse
from datetime import datetime, timedelta
def dentro_de(request, offset):
 offset = int(offset)
 dt = datetime.now() + timedelta(hours=offset)
 html = "En %i hora(s), serán las %s." % (offset, dt)
 return HttpResponse(html)
!"#$%&'
()*+$%&'
+,-./01%2!""http://mysite.com/time/plus/2
42
Residência de Reuso - 2011.1 - Recife/PE
Html dentro da views?
43
Templates
Residência de Reuso - 2011.1 - Recife/PE
Separa a camada de apresentação de forma independente
Linguagem de marcação embarcada dentro do html (Designers :D)
!"#$%&'"(
! "#$%&%'()%()*+,-%(.#($)"("*'&+,-*(%(/'%(-%$%(,'.#$#'.,#'0#1
! 2,-3#&45(,'.#$#'.,#'0#5(61307)8
! 9#'+/%:#(,'.#$#'.,#'0#(6;$%&%(.,5#<%.4&#5=8
44
Templates
Residência de Reuso - 2011.1 - Recife/PE
Baseia-se em 2 objetos:
Template
String a ser devolvida pelo HttpResponse 
(geralmente HTML) com alguns marcadores 
especiais de Django.
Context Um dicionário com os valores a serem 
renderizados no Template.
!"#$%&'"(
! "#$%&'&($#($)*'$+,*'$)#$*%-#.*'/$0#1,2&.#34$5$6*(.#7.348
! 9($*%-#.*$!"#$%&'"34$:*(+#(#$#2$(')*+,$)#$'&2;)&$<=#$
<=#>#1*'$)#?*2?#>$#($#2$@A,B#',*('#$3(*>1&21#(.#$
@0CD4E$,#>*$;(:2=5#()*$#+<=#.&'$#',#:;&2#'$)#$F-&(G*8
! 9($*%-#.*$-.+'"/'34$:*(+#(#$=($0*11*.+&)*.$:*($2*'$
?&2*>#'$<=#$)&($:*(.#7.*$&$=(&$,2&(+22&E$2*'$<=#$)#%#($
='&>'#$,&>&$>#()#>;H&>$=($*%-#.*$0#1,2&.#348
"Bienvenido, {{ user }}."
{'user': 'alatar'}
0#1,2&.#/
6*(.#7./
"Bienvenido, alatar."
45
Exemplo 1
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"(
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
PLANTILLA = """<html><body>
Son las {{ hora }}.
</body></html>"""
def hora_actual(request):
 now = datetime.now()
 t = Template(PLANTILLA)
 c = Context({'hora': now})
 html = t.render(c)
 return HttpResponse(html)
! )*+#"*&"#$%&'()#*(+,"#-"&./012&3"!"#$%&'",-,./0'"1':(
46
Exemplo 2
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"(
! )"*+,-&"#$%&'()#*(+,"#-"&./012&3".$",/0123"&-/0124%.("/0
from django.http import HttpResponse
from django.template import Template, Context
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 fp = open('/home/django/templates/hora.html')
 t = Template(fp.read())
 fp.close()
 c = Context({'hora': now})
 html = t.render(c)
 return HttpResponse(html)
:|
47
Exemplo 3
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"(
! !")*")&"#$%&'()#*(+,"#-"&./012&3"+"','"#$%&'"-.
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 t = get_template('hora.html')
 c = Context({'hora': now})
 html = t.render(c)
 return HttpResponse(html)
TEMPLATE_DIRS = (
 '/home/django/templates',
)
405,647$8
:)
48
Exemplo 3
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"(
! !")*")&"#$%&'()#*(+,"#-"&./012&3"+"','"#$%&'"-.
from django.http import HttpResponse
from django.template.loader import get_template
from django.template import Context
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 t = get_template('hora.html')
 c = Context({'hora': now})
 html = t.render(c)
 return HttpResponse(html)
TEMPLATE_DIRS = (
 '/home/django/templates',
)
405,647$8
:D
49
Exemplo 4
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"(
! "#$%&'()*+,*-.*/(0))"*+"),'-,)"($-*("./
from django.shortcuts import render_to_response
from datetime import datetime
def hora_actual(request):
 now = datetime.now()
 return render_to_response('hora.html', {'hora': now})
:O
50
Lembrete!
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"()*!+$
TEMPLATE_DIRS = (
 '/home/django/templates',
)
!"#$%!&'( )"*
!+,-".
+''!/
&,
-,
0 1+.2+3'"4+./templates."!.,*!2+5+.5"$436.5".2+5+.+''&
0 76$89"$".9$2-*93.*$+.2+3'"4+.26$."-.$6:,3".5".-+.+''.'63.2-+395+5&
TEMPLATE_LOADERS = (
 'django.template.loaders.filesystem.load_template_source',
 'django.template.loaders.app_directories.load_template_source',
)
return render_to_response('website/index.html')
;-4"3$+<8+.3"*<-9=+,-">
!"#$%&'"()*!+$
TEMPLATE_DIRS = (
 '/home/django/templates',
)
!"#$%!&'( )"*
!+,-".
+''!/
&,
-,
0 1+.2+3'"4+./templates."!.,*!2+5+.5"$436.5".2+5+.+''&
0 76$89"$".9$2-*93.*$+.2+3'"4+.26$."-.$6:,3".5".-+.+''.'63.2-+395+5&
TEMPLATE_LOADERS = (
 'django.template.loaders.filesystem.load_template_source',
 'django.template.loaders.app_directories.load_template_source',)
return render_to_response('website/index.html')
;-4"3$+<8+.3"*<-9=+,-">
!"#$%&'"()*!+$
TEMPLATE_DIRS = (
 '/home/django/templates',
)
!"#$%!&'( )"*
!+,-".
+''!/
&,
-,
0 1+.2+3'"4+./templates."!.,*!2+5+.5"$436.5".2+5+.+''&
0 76$89"$".9$2-*93.*$+.2+3'"4+.26$."-.$6:,3".5".-+.+''.'63.2-+395+5&
TEMPLATE_LOADERS = (
 'django.template.loaders.filesystem.load_template_source',
 'django.template.loaders.app_directories.load_template_source',
)
return render_to_response('website/index.html')
;-4"3$+<8+.3"*<-9=+,-">
!"#$%&'"()*!+$
TEMPLATE_DIRS = (
 '/home/django/templates',
)
!"#$%!&'( )"*
!+,-".
+''!/
&,
-,
0 1+.2+3'"4+./templates."!.,*!2+5+.5"$436.5".2+5+.+''&
0 76$89"$".9$2-*93.*$+.2+3'"4+.26$."-.$6:,3".5".-+.+''.'63.2-+395+5&
TEMPLATE_LOADERS = (
 'django.template.loaders.filesystem.load_template_source',
 'django.template.loaders.app_directories.load_template_source',
)
return render_to_response('website/index.html')
;-4"3$+<8+.3"*<-9=+,-">
51
Templates: {{}}
Residência de Reuso - 2011.1 - Recife/PE
Sintaxe simples de templates
Desacoplado de Python
HTML com anabolizantes
Extensível
Designers vão se apaixonar!
!"#$%&'"()*++,,
<html>
 <head>Ejemplo templates</head>
 <body>
 Hola, {{ username }}.
 </body>
</html>
{'username': 'juan'}
<html>
 <head>Ejemplo templates</head>
 <body>
 Hola, juan.
 </body>
</html>
Templates não podem 
executar
código Python!!!!
52
Templates: {{}}
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'()(*+,'
Tags
53
Tags
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"()*'&+(*,-*-.
{% comment %} Bu! {% endcomment %}/0##"1'
203 {% for elemento in lista %}
 <li>{{ elemento }}<li>
{% endfor %}
42 {% if username == "Juan" %}
 Hola Juan, me gustas!
{% else %}
 Hola {{ username }},
{% endif %}
== != > < >= <=
in and or not
54
Filters
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"()*+,%'"-(
<html>
 <head>Ejemplo templates</head>
 <body>
 Hola, {{ username|title }}.
 </body>
</html>
{'username': 'juan'}
<html>
 <head>Ejemplo templates</head>
 <body>
 Hola, Juan.
 </body>
</html>
.'%"
55
Filters
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"()*+,%'"-(
{'value': 123456789}
{{ value|add:”1” }}&.. 123456790
{{ value|filesizeformat }}/%"(,0"12-#&' 117.7MB
{'date': datetime.datetime(2010, 9, 11, 17, 1, 59, 385323) }
{{ date|date:”d M Y” }}.&'" 11 Sep 2010
{{ date|timesince }}3#"(,45" 4 days, 6 hours
{{ date|timeuntil }}3#"643% 1 days, 6 hours
56
Modelos
Residência de Reuso - 2011.1 - Recife/PE
Nós temos objetos e queremos persistí-los
Mapeamento entre Objetos e tabelas
Django tem ORM!
57
Eu crio classes e objetos
Residência de Reuso - 2011.1 - Recife/PE
!"#$%"
from django.db import models
class Books(models.Model):
 name = models.CharField(blank=True, max_length=100)
 created = models.DateTimeField(blank=False)
 available = models.BooleanField(default=True)
!"&'#$($'#$')*+",-./0
!"#$%&'()*"$*+,-.+-,/*"0$"'&1),(/.'2&"1$'23*)+43
!"#$%&'()*"3$453*))*"'$4"!"#$"%&&'()&*"+'(,*-.&/"01$2223
!"6'*)+"0$%&'.'2&"0$4"()0$4)"!4#"50%6*478"'(,*9/#(*(:)3"
58
O ORM converte para SQL
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'(&)$*+,
BEGIN;
CREATE TABLE "website_books" (
 "id" integer NOT NULL PRIMARY KEY,
 "name" varchar(100) NOT NULL,
 "created" datetime NOT NULL,
 "available" bool NOT NULL
);
COMMIT;
BEGIN;
CREATE TABLE "website_books" (
 "id" serial NOT NULL PRIMARY KEY,
 "name" varchar(100) NOT NULL,
 "created" timestamp with time zone NOT NULL,
 "available" boolean NOT NULL
);
COMMIT;
59
Com 1 comando! 
Residência de Reuso - 2011.1 - Recife/PE
$ python manage.py syncdb
60
Configure o seu banco
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'(')*+,#%*-./
 
 DATABASE_ENGINE = 'sqlite3'
 DATABASE_NAME = 'db.sqlite'
 DATABASE_USER = ''
 DATABASE_PASSWORD = ''
 DATABASE_HOST = ''
 DATABASE_PORT = ''
settings.py
61
e se alterar os modelos ?
Residência de Reuso - 2011.1 - Recife/PE
Não atualiza os esquemas existentes! :(
GoHorse: Dropa na mão e rexecuta syncdb!
south
desed
django-evolution
yasdel
Ou aplicações externas:
62
Exemplo 
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&
$ python manage.py syncdb
Creating table auth_permission
Creating table auth_group
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table website_tweet
You just installed Django's auth system, which means you don't have any 
superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'neo'): admin 
E-mail address: user@example.com
Password: 
Password (again): 
Superuser created successfully.
Installing index for auth.Permission model
Installing index for auth.Message model
Installing index for website.Tweet model
63
Exercício 03 
Residência de Reuso - 2011.1 - Recife/PE
Criar o backend da sua app seminarios
Vamos usar o sqlite3
64
Exemplo 
Residência de Reuso - 2011.1 - Recife/PE
Hora de fazer montar consultas!
65
ORM- Consultas
Residência de Reuso - 2011.1 - Recife/PE
$ python manage.py shell
select * from publisher;
!"#$%&'()*+,#,(-#*(./0
ts = Publisher.objects.all()
Model
Manager
QuerySet
66
ORM- Consultas
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'())*+%,&-#))./
class Publisher(models.Model):
 ...
 
 def __unicode__(self):
 return self.name
>>> Publisher.objects.all()
[<Publisher: Publisher object>]
>>> Publisher.objects.all()
[<Publisher: Apress>]
67
ORM- Inserção
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&
>>> p = Publisher(
... name='Apress',
... address='2855 Telegraph Avenue',
... city='Berkeley',
... state_province='CA',
... country='U.S.A.',
... website='http://www.apress.com/')
>>> p.save()
!"
o = Model(...) o.save()
68
ORM- Atualização
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&
>>> ...
>>> p.id
52
>>> p.name = 'Apress Publishing'
>>> p.save()
o.save()
!
!"#$%&
>>> Publisher.objects.all().update(country='USA')
2
>>> ...
>>> p.id
52
>>> p.name = 'Apress Publishing'
>>> p.save()
o.save()
queryset.update(...)
!
"
69
ORM- Deleção
Residência de Reuso - 2011.1 - Recife/PE
!"#"$"
>>> ps = Publisher.objects.all()
>>> ps.delete()
>>> ...
>>> p.id
52
>>> p.delete()
o.delete()
queryset.delete()
!
"
!"#"$"
>>> ps = Publisher.objects.all()
>>> ps.delete()
>>> ...
>>> p.id
52
>>> p.delete()
o.delete()
queryset.delete()
!
"
70
Select 1 resultado
Residência de Reuso - 2011.1 - Recife/PE
!"#"$%&'(&)&*(+,-./'0
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
 ...
MultipleObjectsReturned: get() returned more than one Publisher --
 it returned 2! Lookup parameters were {'country': 'U.S.A.'}
>>> Publisher.objects.get(name="Anaya")
Traceback (most recent call last):
 ...
DoesNotExist: Publisher matching query does not exist.
!"#"$%&'(&)&*(+,-./'0
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
 ...
MultipleObjectsReturned:get() returned more than one Publisher --
 it returned 2! Lookup parameters were {'country': 'U.S.A.'}
>>> Publisher.objects.get(name="Anaya")
Traceback (most recent call last):
 ...
DoesNotExist: Publisher matching query does not exist.
!"#"$%&'(&)&*(+,-./'0
>>> Publisher.objects.get(name="Apress")
<Publisher: Apress>
.get(...)
>>> Publisher.objects.get(country="U.S.A.")
Traceback (most recent call last):
 ...
MultipleObjectsReturned: get() returned more than one Publisher --
 it returned 2! Lookup parameters were {'country': 'U.S.A.'}
>>> Publisher.objects.get(name="Anaya")
Traceback (most recent call last):
 ...
DoesNotExist: Publisher matching query does not exist.
71
Select n resultados
Residência de Reuso - 2011.1 - Recife/PE
!"#"$%&'(&)&*(+,-./'0+
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
.all()
>>> Publisher.objects.filter(
 country="U.S.A.", state_province="CA")
[<Publisher: Apress>]
.filter(...)
!"#"$%&'(&)&*(+,-./'0+
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
.all()
>>> Publisher.objects.filter(
 country="U.S.A.", state_province="CA")
[<Publisher: Apress>]
.filter(...)
!"#"$%&'(&)&*(+,-./'0+
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
.all()
>>> Publisher.objects.filter(
 country="U.S.A.", state_province="CA")
[<Publisher: Apress>]
.filter(...)
RETORNAM QUERYSETS e não LISTAS!
72
Manipulação de consultas
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'()#"*$%'+'",-)./"$%
Modelo.objects.filter(campo1="valor1", campo2="valor2")
!"#$%&'()*+'"#$%,*-*.$/.-/0&'$),01"$)(#$2,*$/3,&4-&-$567
campo__exact=''
campo__iexact=''
campo__contains=''
campo__icontains=''
campo__isnull=T|F
campo__day=31
campo__gt=0
campo__gte=0
campo__lt=0
campo__lte=0
campo__in=[ ,]
campo__month=12
campo__startswith=''
campo__istartswith=''
campo__endswith=''
campo__iendswith=''
campo__range=( ,)
campo__year=2010
!"#$%&'()#"*$%'+'",-)./"$%
Modelo.objects.filter(campo1="valor1", campo2="valor2")
!"#$%&'()*+'"#$%,*-*.$/.-/0&'$),01"$)(#$2,*$/3,&4-&-$567
campo__exact=''
campo__iexact=''
campo__contains=''
campo__icontains=''
campo__isnull=T|F
campo__day=31
campo__gt=0
campo__gte=0
campo__lt=0
campo__lte=0
campo__in=[ ,]
campo__month=12
campo__startswith=''
campo__istartswith=''
campo__endswith=''
campo__iendswith=''
campo__range=( ,)
campo__year=2010
73
Order By
Residência de Reuso - 2011.1 - Recife/PE
!"#$"%&'
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
.order_by(...)
>>> Publisher.objects.order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
>>> Publisher.objects.order_by("-name", "country")
[<Publisher: O'Reilly>, <Publisher: Apress>]
!"#$%#&'()*+%,'-
!"#$"%&'
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: O'Reilly>]
.order_by(...)
>>> Publisher.objects.order_by("-name")
[<Publisher: O'Reilly>, <Publisher: Apress>]
>>> Publisher.objects.order_by("-name", "country")
[<Publisher: O'Reilly>, <Publisher: Apress>]
!"#$%#&'()*+%,'-
74
Relacionamentos One-to-One
Residência de Reuso - 2011.1 - Recife/PE
!"#$%"&'()*"+%,
OneToOneField
class Coche(models.Model):
 motor = OneToOneField(Motor)
class Motor(models.Model):
 ...
>>> c.motor
<Motor: Motor object>
>>> m.coche
<Coche: Coche object>
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
4
1
1
!"#$%"&'()*"+%,
OneToOneField
class Coche(models.Model):
 motor = OneToOneField(Motor)
class Motor(models.Model):
 ...
>>> c.motor
<Motor: Motor object>
>>> m.coche
<Coche: Coche object>
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
4
!"#$%"&'()*"+%,
OneToOneField
class Coche(models.Model):
 motor = OneToOneField(Motor)
class Motor(models.Model):
 ...
>>> c.motor
<Motor: Motor object>
>>> m.coche
<Coche: Coche object>
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
4
!"#$%"&'()*"+%,
OneToOneField
class Coche(models.Model):
 motor = OneToOneField(Motor)
class Motor(models.Model):
 ...
>>> c.motor
<Motor: Motor object>
>>> m.coche
<Coche: Coche object>
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
4
75
Relacionamentos One-to-Many
Residência de Reuso - 2011.1 - Recife/PE
1
n
!"#$%"&'()*"+%,
ForeignKeyField
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog)
>>> p.blog
<Blog: Blog object>
>>> b.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
/
!"#$%"&'()*"+%,
ForeignKeyField
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog)
>>> p.blog
<Blog: Blog object>
>>> b.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
/
!"#$%"&'()*"+%,
ForeignKeyField
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog)
>>> p.blog
<Blog: Blog object>
>>> b.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
/
!"#$%"&'()*"+%,
ForeignKeyField
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog)
>>> p.blog
<Blog: Blog object>
>>> b.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
4
/
76
Relacionamentos Many-to-Many
Residência de Reuso - 2011.1 - Recife/PE
m
n
!"#$%"&'()*"+%,
ManyToManyField
class Post(models.Model):
 tags = ManyToManyField(Tag)
class Tag(models.Model):
 ...
>>> p.tags.add(t1, t2)
>>> p.tags.all()
[<Tag: Tag object>, ...]
>>> t.post_set.add(p1, p2)
>>> t.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
/
$
!"#$%"&'()*"+%,
ManyToManyField
class Post(models.Model):
 tags = ManyToManyField(Tag)
class Tag(models.Model):
 ...
>>> p.tags.add(t1, t2)
>>> p.tags.all()
[<Tag: Tag object>, ...]
>>> t.post_set.add(p1, p2)
>>> t.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
/
$
!"#$%"&'()*"+%,
ManyToManyField
class Post(models.Model):
 tags = ManyToManyField(Tag)
class Tag(models.Model):
 ...
>>> p.tags.add(t1, t2)
>>> p.tags.all()
[<Tag: Tag object>, ...]
>>> t.post_set.add(p1, p2)
>>> t.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
/
$
!"#$%"&'()*"+%,
ManyToManyField
class Post(models.Model):
 tags = ManyToManyField(Tag)
class Tag(models.Model):
 ...
>>> p.tags.add(t1, t2)
>>> p.tags.all()
[<Tag: Tag object>, ...]
>>> t.post_set.add(p1, p2)
>>> t.post_set.all()
[<Post: Post object>, ...]
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
/
$
77
 Ponteiros inversos
Residência de Reuso - 2011.1 - Recife/PE
1
n
!"#$%"&'()*"+%,
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog:Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
+
(
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
!"#$%"&'()*"+%,
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog: Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
+
(
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
!"#$%"&'()*"+%,
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog: Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
+
(
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
!"#$%"&'()*"+%,
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
class Blog(models.Model):
 ...
class Post(models.Model):
 blog = ForeignKeyField(Blog, related_name='posts')
>>> p.blog
<Blog: Blog object>
>>> b.posts.all()
[<Post: Post object>, ...]
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
+
(
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
78
Laziness
Residência de Reuso - 2011.1 - Recife/PE
Otimização!! Consulta só realizada quando necessário!
!"#$%&''
! "#$%&'($)*+#$%'()*%$,%,-,&)+#./(%&)#(0'%.,#*1,(+,%$,%
(,&,$2+,%'3+,(,.%*'$%'3-,+'$4%5(%*#$%$26)2,(+,$%$2+)#&2'(,$7
! 8+,.#&2'(,$
! 9*2&2(6
! 9,.2#*2:#&2;(
• repr()
• len() !!!
• list()
• bool()
for p in Publisher.objects.all():
Publisher.objects.filter(country='USA')[0]
<=#&>?@
[<Publisher: Publisher object>]
len(Publisher.objects.all())
list(Publisher.objects.all())
if Publisher.objects.filter(country='USA'):
!"#$%&''
! "#$%&'($)*+#$%'()*%$,%,-,&)+#./(%&)#(0'%.,#*1,(+,%$,%
(,&,$2+,%'3+,(,.%*'$%'3-,+'$4%5(%*#$%$26)2,(+,$%$2+)#&2'(,$7
! 8+,.#&2'(,$
! 9*2&2(6
! 9,.2#*2:#&2;(
• repr()
• len() !!!
• list()
• bool()
for p in Publisher.objects.all():
Publisher.objects.filter(country='USA')[0]
<=#&>?@
[<Publisher: Publisher object>]
len(Publisher.objects.all())
list(Publisher.objects.all())
if Publisher.objects.filter(country='USA'):
79
Exercício 04 
Residência de Reuso - 2011.1 - Recife/PE!"#$%&!'()*(+&"(*',(-(+&#./)*(&0&$(1(*(
80
Interface Administrativa
Residência de Reuso - 2011.1 - Recife/PE
81
Interface Administrativa
Residência de Reuso - 2011.1 - Recife/PE
82
djang.contrib.admin
Residência de Reuso - 2011.1 - Recife/PE
Instalação 1/3
83
djang.contrib.admin
Residência de Reuso - 2011.1 - Recife/PE
Instalação 2/3
!"#$%&'#()*$+',$-.#/#0*1$
INSTALLED_APPS = (
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.sites',
 'django.contrib.admin',
 ...
)
!"#$%!&'(
1
84
djang.contrib.admin
Residência de Reuso - 2011.1 - Recife/PE
Instalação 3/3
!"#$%&'(%)*+,&%,-.
$ python manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model
!"#$%&'$()*&+*,*&-(*,
!"#$%&'(%)*+,&%,-.
$ python manage.py syncdb
Creating table django_admin_log
Installing index for admin.LogEntry model
!"#$%&'$()*&+*,*&-(*,
Acesse http://localhost:8000/admin
85
Opa! Falta registrar os modelos
Residência de Reuso - 2011.1 - Recife/PE
Criar o módulo admin.py
!"#$%&'(
! "#$#%!''%$&'&%$&%(&)&*%&+%,-./0
! 1&2)&%3-4%5/$&+/,%,&*6)%78,8'+&,%$&,$&%&+%#$58)%.%
9&*58(&%9&*,/)#+8:#*%,-%#,9&;(/0
from django.contrib import admin
from website.models import Tweet
class TweetAdmin(admin.ModelAdmin):
 list_display = ('id','user','message','timestamp')
 
admin.site.register(Tweet, TweetAdmin)
Cada app deve ter o seu, pode ser configurável!
86
Exercício 04 
Residência de Reuso - 2011.1 - Recife/PE!"#$%&'#(")
87
Forms
Residência de Reuso - 2011.1 - Recife/PE
3 componentes
Widget
Componente Visual
Field
Campo Lógico
Form
!"#$%$&'()*"+,-#.#$
Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
EmailField
IPAddressField
widget, initial, error, ...
Form !*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
ContactForm [nombre, email, telefono, mensaje, ...]
!"#$%$&'()*"+,-#.#$
Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
EmailField
IPAddressField
widget, initial, error, ...
Form !*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
ContactForm [nombre, email, telefono, mensaje, ...]
!"#$%$&'()*"+,-#.#$
Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
TextInput
CheckboxInput
<input type='text'...>
<input type='checkbox'...>
Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
EmailField
IPAddressField
widget, initial, error, ...
Form !*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
ContactForm [nombre, email, telefono, mensaje, ...]
Formulário em si
88
Criação de Formulário
Residência de Reuso - 2011.1 - Recife/PE
Passo 1: Definição de um formulário forms.py
http://docs.djangoproject.com/en/dev/ref/forms/fields/
89
Criação de Formulário
Residência de Reuso - 2011.1 - Recife/PE
Passo 2: Definição do template do Formulário
contato.html
90
Criação de Formulário
Residência de Reuso - 2011.1 - Recife/PE
Passo 3: Definição da view do Formulário
91
Criação de Formulário
Residência de Reuso - 2011.1 - Recife/PE
Forms tem validação própria! Cool :D
!"#$%"&$'()*+,*$"
from django import forms
class ContactForm(forms.Form):
 subject = forms.CharField(max_length=100)
 email = forms.EmailField(required=False)
 message = forms.CharField(widget=forms.Textarea)
 def clean_message(self):
 message = self.cleaned_data['message']
 num_words = len(message.split())
 if num_words < 4:
 raise forms.ValidationError("Not enough words!")
 return message
!"#$%"&'()"*)+%+)',+-.#+/.01'$23)+'+&"/.+#+'+'/+#+'4.$-#'
#$-'5")%6-+)."'$&/).7.$1#"'61'%83"#"'clean_<fieldname>9
92
Forms a partir de Models
Residência de Reuso - 2011.1 - Recife/PE
Aqui é DRY meu caro!!
!"#$%&'&('#)#&*+&,"*+-%
from django.db import models
class Author(models.Model):
 name = models.CharField(max_length=100)
 birth_date = models.DateField(blank=True, null=True)
 country = models.ModelChoiceField(Country)
 ...
from django import forms
from books.models import Author
 
class AuthorForm(forms.ModelForm):
 class Meta:
 model = Author
 exclude = ('country',)
!"#$%&'()
."#$%/(0
93
Exercício 04 
Residência de Reuso - 2011.1 - Recife/PE
!"#$"%"&"'(")"
Alguns truques agora...
94
Django Avançado
Residência de Reuso - 2011.1 - Recife/PE
1. Middleware
2. Caching
3. Deploying
4. Apps Recomendadas
95
Django Avançado
Residência de Reuso - 2011.1 - Recife/PE
1. Middleware
2. Caching
3. Deploying
4. Apps Recomendadas
96
Middleware
Residência de Reuso - 2011.1 - Recife/PE
Permite incrementar a funcionalidade injetando fluxo de 
execução em Django
!"##$%&'(%
!"#$%&'()*&$&#+'),)'$-./+)"/01)202$'&.31)40,1&$
5.&$#&$)/#&'*0$&/$&1$6.7"$2&$&7&+.+)8/$2&$970/:"
97
Middleware
Residência de Reuso - 2011.1 - Recife/PE
!"##$%&'(%
class MyMiddleware(object):
 def process_request(self, request):"""Se ejecuta antes de que Django decida a quâˆ!© View llamar.
 -> HttpRequest(): Se corta el flujo de middleware.
 -> None: El flujo sigue con el siguiente middleware."""
 # ...
 
 def process_view(self, request, view_func, view_args, view_kwargs):
 """Se ejecuta antes de que se llame a la View.
 -> HttpRequest(): Se corta el flujo de middleware.
 -> None: El flujo sigue con el siguiente middleware."""
 # ...
 def process_response(self, request, response):
 """Se ejecuta despuâˆ!©s de que la View devuelva una response.
 -> HttpResponse()"""
 # ...
 def process_exception(self, request, exception):
 """Se ejecuta cuando una View lanza una excepciâˆ!≥n.
 -> HttpResponse().
 -> None: La excepciâˆ!≥n se propaga hasta el cliente."""
 # ...
98
Middleware
Residência de Reuso - 2011.1 - Recife/PE
!"##$%&'(%
!"#"$%&'()"'*#+,)*-'#)"&.-%'$*//,"01-"'"#'",',)21-'
()"'#%&'+%#3"#214')%*"%*#+,%*,-.%*)',%$,+(#%*,#%,
%/%-.-"0*,%*,$',1%2.%3),4,%*,$',1%35+*3%5
MIDDLEWARE_CLASSES = (
 'django.middleware.common.CommonMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
)
Registrar o middlewares no settings.py
99
Django Avançado
Residência de Reuso - 2011.1 - Recife/PE
1. Middleware
2. Caching
3. Deploying
4. Apps Recomendadas
100
Caching
Residência de Reuso - 2011.1 - Recife/PE
Sempre importante estar aliviando o banco de consultas...
!"!#$%&
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
 ...
'$()*
!"!#$%&
'()*'+,+'
>>> from django.core.cache import cache
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'
!"#$%&#'()*)+%*,()-*./-0%,(12#($%(#34%5#(/-%('%(2-%$*('%,0*.06*,7
!(8-%,9:%5'
!(;0'5*'
!(777
101
Django Avançado
Residência de Reuso - 2011.1 - Recife/PE
1. Middleware
2. Caching
3. Deploying
4. Apps Recomendadas
102
Deploying
Residência de Reuso - 2011.1 - Recife/PE
Por o sistema em produção
VirtualEnv + PIP + Fabric
103
Virtualenv
Residência de Reuso - 2011.1 - Recife/PE
Projeto independente do sistema
Ou seja cada projeto com suas dependências 
específicas
!"#$%&'()*
!"#$%&%#$%#'()*'+,&-%.)*$%*-)/*-(01%12)/*$%-*/(.%,)3
!4)$)*&1+5%'.+*6%#%*/7*87%9+*$%*-(01%12)/*%#*-)*:%1/(;#*<7%*#%'%/(.)
!=(#*,(%$+*)*)'.7)-(>)1
!=(#*,(%$+*)*,(91)1
!%.'333
$ virtualenv --no-site-packages mi_entorno
+#(&#
Adeus dor de cabeça de migrar, atualizar, etc.
!"#$%&'()*
!"#$%&%#$%#'()*'+,&-%.)*$%*-)/*-(01%12)/*$%-*/(.%,)3
!4)$)*&1+5%'.+*6%#%*/7*87%9+*$%*-(01%12)/*%#*-)*:%1/(;#*<7%*#%'%/(.)
!=(#*,(%$+*)*)'.7)-(>)1
!=(#*,(%$+*)*,(91)1
!%.'333
$ virtualenv --no-site-packages mi_entorno
+#(&#
$ source mi_entorno/bin/activate
&+,*&#
104
Pip
Residência de Reuso - 2011.1 - Recife/PE
Gerenciador de Pacotes
Você pode criar uma lista de requisitos (requirements) 
para instalação automática! :D
!"!
!"#$%&'()#(*+,-#%#$()#.($/0.&(12(34
!5#'6/%#(#$*#7/87+'(-9(87:#'&()#(;<=>?;<@<ABC(7&9(-9(./$%+)&()#(
*+,-#%#$(+(/9$%+.+'D
4E+90&FF2D1D2
*$G7&*01
H##)*+'$#'FFID2
$%'/*&0'+6FF2DJ
"K:+'%L'+**#'FFMDN
pip install -E mi_entorno -r REQUIREMENTS
!"!
!"#$%&'()#(*+,-#%#$()#.($/0.&(12(34
!5#'6/%#(#$*#7/87+'(-9(87:#'&()#(;<=>?;<@<ABC(7&9(-9(./$%+)&()#(
*+,-#%#$(+(/9$%+.+'D
4E+90&FF2D1D2
*$G7&*01
H##)*+'$#'FFID2
$%'/*&0'+6FF2DJ
"K:+'%L'+**#'FFMDN
pip install -E mi_entorno -r REQUIREMENTS
105
Fabric
Residência de Reuso - 2011.1 - Recife/PE
“Repetition leads to boredom, boredom to horrifying mistakes, 
horrifying mistakes to God-I-wish-I-was-still-bored”
!"#$%&
env.user = "example"
env.hosts = ["example.com"]
def deploy():
 run('svn up /home/example/')
 sudo('/etc/init.d/lighttpd restart')
'"#()*+,-
Repetition leads to boredom, boredom to horrifying mistakes, 
horrifying mistakes to God-I-wish-I-was-still-bored“
!"#$%&
env.user = "example"
env.hosts = ["example.com"]
def deploy():
 run('svn up /home/example/')
 sudo('/etc/init.d/lighttpd restart')
'"#()*+,-
fabric deploy
./0
Repetition leads to boredom, boredom to horrifying mistakes, 
horrifying mistakes to God-I-wish-I-was-still-bored“
106
Django Avançado
Residência de Reuso - 2011.1 - Recife/PE
1. Middleware
2. Caching
3. Deploying
4. Apps Recomendadas
107
django-registration
Residência de Reuso - 2011.1 - Recife/PE
Sistema completo de cadastro de usuários
DRY!!
Instalação Copy and Paste
!"#$%&'()%*+,(#-&$
!"#$%%&'(&)*+,(-./0%)&,/1.2(/)3%45610.7/,0'2(/68.1%
%6*896(,%*.3#:,(,%
%6*896(,%;6*8968.1<+,=>%
%?/,0'2(,/%
%?/,0'2(,/%*.3#:,(,%
%?/,0'2(,/%*:.2,4%
%?:.0'1%
%?:.0.)(%
%?#622@./4%*!610,%
%?#622@./4%*!610,%4.1,%
%?#622@./4%/,2,(%
%?#622@./4%/,2,(%*.1A/3%;(.+,1>
%?#622@./4%/,2,(%*.3#:,(,%
%?#622@./4%/,2,(%4.1,%
%?/,6*896(,%
108
django-socialregistration
Residência de Reuso - 2011.1 - Recife/PE
O django-registration só que anabolizado!
Autenticação com Twitter, Facebook, oAuth, openID
Integração perfeita com django.contrib.auth
!"#$%&'(&)*#+,-%*(.,#/&$
!"#$%%&'(!)*+,-.%/01!'2&#).#3'2%4502&-61-,'0789&'1(80:-2
;<-2=&)80,'>2?192,'770
;@)(92:,0,'>2?,-2$
;(A'"98B?C0,9*--3B?-0)(!B?-#92'4
;D2(9&80,'>2?#98C9,(0?,-2?,-2(8'*+0)(!
109
django-piston
Residência de Reuso - 2011.1 - Recife/PE
Framework Django para construção de serviços RESTful
Fácil de instalar
!"#$%&'()*+&$
!"#$%%&'(&)*+,(-./0%1,2#,/3%41530.6#'2(.3%7'+'%8.9,
:;</59,7./+;#5/5;*/,5/;=>?2;@ABCD)E
:;F)G;DH*'E;'32(5E5*'I3
:;B,/'5E'J5*'I3;5$
:KBLMN;O=FPN;>G(!.3;>G*+E,N;QFP;---
:L=)(!
:@,*.9,3454.;RRRRR
Suporte para YAML, JSON, XML, etc.
OAuth
!"#$%&'()*+&$
!"#$%%&'(&)*+,(-./0%1,2#,/3%41530.6#'2(.3%7'+'%8.9,
:;</59,7./+;#5/5;*/,5/;=>?2;@ABCD)E
:;F)G;DH*'E;'32(5E5*'I3
:;B,/'5E'J5*'I3;5$
:KBLMN;O=FPN;>G(!.3;>G*+E,N;QFP;---
:L=)(!
:@,*.9,3454.;RRRRR
110
Residência de Reuso - 2011.1 - Recife/PE
!"#$%&'"#()*#+,)-)./
Apenas uma ponta do iceberg
111
Lembre-se da comunidade!
Residência de Reuso - 2011.1 - Recife/PE
http://python.org.br
http://djangobrasil.org
http://pug-pe.python.org.br
#django-br
#python-br
112
Trabalho da Semana
Residência de Reuso - 2011.1 - Recife/PE
Trabalho para 5 pessoas
Criar um sistema em Django com o assunto visto até aqui
O sistema deve ter no mínimo 10 entidades
O sistema deve ter controle de acesso 
(ver django-registration)
Modelagem vocês decidem
Apresentar pontos positivos e negativos durante o uso da 
tecnologia
113
Referências e Créditos
Residência de Reuso - 2011.1 - Recife/PE
Desenvolvimento web com Python e Django
http://www.slideshare.net/igorsobreira/desenvolvimento-web-com-python-e-django
Django: Disfruta Programando
http://www.slideshare.net/etox/django-eghost-2010
Tutoriais DjangoBrasil
http://docs.djangobrasil.org/intro/tutorial01.html
114
Bibliografia
Residência de Reuso - 2011.1 - Recife/PE
The Definitive Guide to Django: Web Development Done Right. Adrian 
Holovaty, Jacob K. Ed. Appress ISBN-13: 978-1430219361
Pro Django (1st ed.) Marty Alchin. 2008. . Apress, Berkely, CA, USA. ISBN - 
1430210478
Python e Django - Desenvolvimento Ágil de Aplicações Web - Osvaldo 
Santana Neto e Thiago Galesi; Editora Novatec ISBN. 9788575222478.115
Apresentando
Marcel P. Caraciolo
caraciol@gmail.com
Residência RISE - 2011
116
Exercício 01
Residência de Reuso - 2011.1 - Recife/PE
Vamos construir um mini-sistema de submissão 
de palestras do nosso seminário
1. Criar um projeto seminario
2. Criar uma app trabalhos
3. Criar uma view index redirecionando para 
uma página html de boas vindas usando 
templates.
117
Exercício 05 
Residência de Reuso - 2011.1 - Recife/PE
Vamos criar a nossa interface administrativa para o nossos 
modelos recém-criados
118
Exercício 04 
Residência de Reuso - 2011.1 - Recife/PE
Vamos criar os modelos para Trabalho e Palestrante
Trabalho
usuario: User
titulo: String
descricao: String
slides: File
status: Integer
name
Palestrante
*1. *
119
Exercício 02
Residência de Reuso - 2011.1 - Recife/PE
Vamos criar 2 novos templates
1.trabalhos.html
2. detalhes.html
120
Exercício 06 
Residência de Reuso - 2011.1 - Recife/PE
Vamos construir um formulário simples de submissão de palestras!
121

Outros materiais