WhatsApp 9892124323 ✓Call Girls In Kalyan ( Mumbai ) secure service
Django Framework Introduction
1. Apresentando
Marcel P. Caraciolo
@marcelcaraciolo
Residência RISE - 2011
Saturday, May 21, 2011
2. O que é Django ?
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
3. Não é Jungle. É Django.
O que é Django ?
Saturday, May 21, 2011
4. Não é Django Reinhardt ... na verdade é
Saturday, May 21, 2011
5. É um framework web
Criado em 2005 Aplicação Web
Lawrence, Kansas -
Lawerence Journal World
Licença BSD
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
6. É um framework web
Criado em 2005 DRY Aplicação Web
Lawrence, Kansas - Repeat Yourself
Don’t
Lawerence Journal World
Licença BSD
http://www.flickr.com/photos/plinton/215437652/
Saturday, May 21, 2011
7. Django é Python!
!"#$%&'()*"*
! *+"(,%-'./0.
Escrito em Python
!"#$$$%&'(&)*+,
Focado em
Desenvolvimento Ágil
Don’t Repeat yourself
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
8. Projeto == Várias aplicações
django.contrib.admin django-registration
south django.contrib.comments
django-mailer django-pagination
...
http://djangopackages.com
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
9. E isto é MVC ?
Models
Controllers Views
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
10. Alguns chamam de MTV
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
11. Alguns chamam de MTV
Model - Template - Views
Saturday, May 21, 2011
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
Saturday, May 21, 2011
13. Aplicações
Instalando a aplicação
Coloque no path (PYTHONPATH)
Coloque no INSTALLED_APPS no settings.py
settings.py
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
14. Aplicações
A aplicação é auto-contida
tests.py
urls.py
templates/
admin.py
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
15. Fácil de Usar
$ pip install django
$ django-admin.py startproject dwitter
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
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
Saturday, May 21, 2011
18. Fácil de Usar
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
19. !"#$%&'#()'*+)&,-.
Quem usa ?
!"#$$$ Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
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
Saturday, May 21, 2011
23. Banco de Dados
12 linhas em Python ... :(
Saturday, May 21, 2011
24. Banco de Dados
12 linhas em Python ... :(
!"#$%!&'()*+"(,-./0-,$1-223045
Saturday, May 21, 2011
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
Saturday, May 21, 2011
26. Criar tabelas?! Fácil!
$ python manage.py syncdb
Crie as tabelas no banco. E pronto!
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
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
Saturday, May 21, 2011
28. Vamos à prática!
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
29. !"#$%&'()(*+,%#-.'/0%
Instalação Python
$ sudo apt-get install python
$ sudo apt-get install python
sudo apt-get install python
http://www.python.org/download
http://www.python.org/download/
http://www.python.org/download/
Já vem com python instalado
!"#$%&'#()*+%,"-./0'%.)1%2'*1,#"'1%2.5.4%0%2.6.1
!"#$%&'#()*+%,"-./0'%.)1%2'*1,#"'1%2.5.4%0%2.6.1
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
30. 2)3$45(6-/1) 2)!"*,(,1)
Instalação de Banco de Dados
2)7"/+%'-89: 2)8<=(/-)89:)>#<?@-'-
2);<89: 2)A.;)0.B
2);54'"/"C)89:)8-'D-')BEEF
2)3'(46-
Poderíamos escolher dentre vários SGBD’s
2)G5'-=5',
2)!"#$%& 2)30.!
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
31. Instalação de Banco de Dados
Vamos usar o Sqlite!
Precisa instalar ?! Não :D
Python já vem com SGBD incluso!
http://docs.python.org/library/sqlite3.html
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
32. Instalação de Django
3 maneiras!
apt-get install python-django
http://www.djangoproject.com/download
python setup.py install
http://www.djangoproject.com/svn/django/trunk
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
33. !""#$%&'()
!""#$%&'()
!""#$%&'()
Instalação de Django
>>> import django
>>> import django
>>> import django
>>> django.VERSION
>>> django.VERSION
>>> django.VERSION
>>> import 'final', 0)
(1, 1, 0, django
>>> django.VERSION 0)
(1, 1, 0, 'final',
(1, 1, 0, 'final', 0)
(1, 1, 0, 'final', 0)
>>> import django
>>> import(most recent call last):
>>> import django
Traceback
django
>>> import (most recent 1, inlast):
Traceback django call
Traceback (most recent call last):
File "<stdin>", line <module>
File "<stdin>", line 1, in last):
"<stdin>", line call <module>
1, in <module>
Traceback (most recent named django
File
ImportError: No module
ImportError: No module 1, in <module>
File "<stdin>", line named django
ImportError: No module named django
ImportError: No module named django
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
34. !"#$"%&'#()"*%+"*,#-)*
Criando um projeto 5#%6%7-8#"*(%9:;
$ django-admin.py startproject seminario
$ django-admin.py startproject dwitter
__init__.py
manage.py
settings.py
urls.py
!"#$%&'"(%")*"+,'-(.&'///"0"%%./%*(%0#%1/%2#3#444
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
35. Criando um projeto
!"#$%!&'( Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
36. !""#$%#"&$'()*"+&,"+-(%*+
Criando um projeto
.(&/&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.
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
37. !"#$%&$'()&*+
Entendendo sua App
!!"#$!%&%!+,%- "'()*%&%.%/0-)1% #!+),!$*"!,%&%234-"5%6
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
38. !"#$%&%'($)*$
urls.py
! "#$%&'()*$+,-$./&$+&,-+$&*.*$/0(),+$1($(2,)+1+$/+)+$#+3$
/(4&5*2(3$6778
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
9($1(%2(2$:;<3$(#(=+2,(3$.(15+2,($(>/)(35*2(3$)(=0#+)(3$
requisições para as respectivas views
?0($)(15)5=(2$+$@02&5*2(3$1($0(12$./&
'E/FGG.B35,(A&*.G+H*0,G 0)#3A/B
I0)#/+E()23J
',.# C5(D3A/B ...
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
39. !"#$%&%'($)*$
views.py
! "#$%&'()*'$+,$-),./012$3,()4,$(565$1#376,835/$&'$549,85$
Módulo views.py tem funções com parâmetros um objeto HttpRequest
+,-"./0.$)$2$85+5/$:5/$1#376,835/$+,$:#$;<"$(#18&3#+5/=$
Retorna um objeto HttpResponse
8,'),'+5$>&,$+,-5:-,3$/),613,$&'$549,85$+,-".$-12$.
+,-"./0.$)345%666
-),./012
+,-".$-12$.34
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
40. !"#$%&%'($)*$
Exemplo!"#$%&%'($)*$
+,-./01%2!""http://mysite.com/time
+,-./01%2!""http://mysite.com/time
http://mysite.com.time
from django.conf.urls.defaults import * *
from django.conf.urls.defaults import
from mysite.views import hora_actual
from mysite.views import hora_actual
!"#$%&' urlpatterns
!"#$%&' urlpatterns =
urls.py = patterns('',
patterns('',
(r'^time/$', hora_actual),
)(r'^time/$', hora_actual),
)
from django.http import HttpResponse
from datetime import datetime
from django.http import HttpResponse
from datetime import datetime
()*+$%&' def hora_actual(request):
now = datetime.now()
()*+$%&'
views.py def hora_actual(request):% now
html = "Son las %s."
= datetime.now()
nowreturn HttpResponse(html)
html = "Son las %s." % now
return HttpResponse(html)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
41. !"#$%&%'($)*$
Exemplo 2
+,-./01%2!""http://mysite.com/time/plus/2
+,-./01%2!""http://mysite.com/time/plus/2
http://mysite.com.time/plus/2
from django.conf.urls.defaults import *
from django.conf.urls.defaults import *
from mysite.views import dentro_de
from mysite.views import dentro_de
urls.py
!"#$%&'
!"#$%&' urlpatterns = patterns('',
urlpatterns = patterns('',
(r'^time/plus/(d{1,2})/$', dentro_de),
(r'^time/plus/(d{1,2})/$', dentro_de),
)
)
from django.http import HttpResponse
from django.http import HttpResponse
from datetime import datetime, timedelta
from datetime import datetime, timedelta
def dentro_de(request, offset):
views.py
()*+$%&'
()*+$%&'
def offset = int(offset)
dentro_de(request, offset):
offset = int(offset)
dt = datetime.now() + timedelta(hours=offset)
dt = datetime.now() + serán las %s." % (offset, dt)
html = "En %i hora(s), timedelta(hours=offset)
html = "En %i hora(s), serán las %s." % (offset, dt)
return HttpResponse(html)
return HttpResponse(html)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
42. Html dentro da views?
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
43. !"#$%&'"(
Templates
! "#$%&%'()%()*+,-%(.#($)"("*'&+,-*(%(/'%(-%$%(,'.#$#'.,#'0#1
Separa a camada de apresentação de forma independente
! 2,-3#&45(,'.#$#'.,#'0#5(61307)8
! Linguagem de marcação embarcada dentro do html (Designers :D)
9#'+/%:#(,'.#$#'.,#'0#(6;$%&%(.,5#<%.4=8
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
44. !"#$%&'"(
Templates
! "#$%&'&($#($)*'$+,*'$)#$*%-#.*'/$0#1,2&.#34$5$6*(.#7.348
Baseia-se em 2 objetos:
! 9($*%-#.*$!"#$%&'"34$:*(+#(#$#2$(')*+,$)#$'&2;)&$<=#$
String a ser devolvida pelo HttpResponse
Template (geralmente HTML) com alguns marcadores
<=#>#1*'$)#?*2?#>$#($#2$@A,B#',*('#$3(*>1&21#(.#$
especiais de Django.
@0CD4E$,#>*$;(:2=5#()*$#+<=#.&'$#',#:;&2#'$)#$F-&(G*8
! 9($*%-#.*$-.+'"/'34$:*(+#(#$=($0*11*.+&)*.$:*($2*'$
?&2*>#'$<=#$)&($:*(.#7.*$&$=(&$,2&(+22&E$2*'$<=#$)#%#($
Um dicionário com os valores a serem
='&>'#$,&>&$>#()#>;H&>$=($*%-#.*$0#1,2&.#348
Context
renderizados no Template.
0#1,2&.#/ "Bienvenido, {{ user }}."
"Bienvenido, alatar."
6*(.#7./ {'user': 'alatar'}
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
45. !"#$%&'"(
Exemplo 1
! :(
)*+#"*&"#$%&'()#*(+,"#-"&./012&3"!"#$%&'",-,./0'"1'
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)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
46. !"#$%&'"(
Exemplo 2
! )"*+,-&"#$%&'()#*(+,"#-"&./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)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
47. !"#$%&'"(
Exemplo 3
!:)!")*")&"#$%&'()#*(+,"#-"&./012&3"+"','"#$%&'"-.
TEMPLATE_DIRS = (
405,647$8 '/home/django/templates',
)
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)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
48. !"#$%&'"(
Exemplo 3
! !")*")&"#$%&'()#*(+,"#-"&./012&3"+"','"#$%&'"-.
:D
TEMPLATE_DIRS = (
405,647$8 '/home/django/templates',
)
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)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
49. !"#$%&'"(
Exemplo 4
:O
! "#$%&'()*+,*-.*/(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})
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
56. Modelos
Nós temos objetos e queremos persistí-los
Mapeamento entre Objetos e tabelas
Django tem ORM!
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
57. !"#$%"
Eu crio classes e objetos
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"
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
58. !"#$%&'(&)$*+,
O ORM converte para SQL
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; Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
59. Com 1 comando!
$ python manage.py syncdb
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
60. Configure o seu banco
!"#$%&'(')*+,#%*-./
DATABASE_ENGINE = 'sqlite3'
DATABASE_NAME = 'db.sqlite'
DATABASE_USER = ''
DATABASE_PASSWORD = ''
DATABASE_HOST = ''
DATABASE_PORT = ''
settings.py
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
61. e se alterar os modelos ?
Não atualiza os esquemas existentes! :(
GoHorse: Dropa na mão e rexecuta syncdb!
Ou aplicações externas:
south
desed
django-evolution
yasdel
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
62. Exemplo !"#$%&
$ 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
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
63. Exercício 03
Criar o backend da sua app seminarios
Vamos usar o sqlite3
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
64. Exemplo
Hora de fazer montar consultas!
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
65. ORM- Consultas
!"#$%&'()*+,#,(-#*(./0
$ python manage.py shell
select * from publisher;
ts = Publisher.objects.all()
Model
Manager
QuerySet
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
74. !"#$%"&'()*"+%,
!"#$%"&'()*"+%,
!"#$%"&'()*"+%,
!"#$%"&'()*"+%,
Relacionamentos One-to-One
OneToOneField
OneToOneField
OneToOneField
class OneToOneField
classCoche(models.Model):
Coche(models.Model):
44 class Coche(models.Model):
motor = =OneToOneField(Motor)
motor OneToOneField(Motor)
1 4 class Coche(models.Model):
motor = OneToOneField(Motor)
4 motor = OneToOneField(Motor)
class Motor(models.Model):
class Motor(models.Model):
44 class Motor(models.Model):
...
...
4 class Motor(models.Model):
...
14 ...
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%(
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
3+)-.)(&)&-*$./0
3+)-.)(&)&/%(%1+%(
>>> c.motor
>>> c.motor
3+)-.)(&)&-*$./0
>>> m.coche
>>> m.coche
3+)-.)(&)&/%(%1+%(
<Motor: Motor object>
<Motor: Motor object>
>>> c.motor
3+)-.)(&)&-*$./0
<Coche: Coche object>
<Coche: Coche object>
>>> m.coche
<Motor: Motor object>
>>> c.motor <Coche: Coche object>
>>> m.coche
<Motor: Motor object> <Coche: Coche object>
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
75. !"#$%"&'()*"+%,
!"#$%"&'()*"+%,
!"#$%"&'()*"+%,
Relacionamentos One-to-Many
!"#$%"&'()*"+%,
ForeignKeyField
ForeignKeyField
ForeignKeyField
44
ForeignKeyField
class Blog(models.Model):
class Blog(models.Model):
...
...
1 4
class Blog(models.Model):
class Blog(models.Model):
...
4 ...
class Post(models.Model):
class Post(models.Model):
// blog ==ForeignKeyField(Blog)
blog ForeignKeyField(Blog)
class Post(models.Model):
/
n / class Post(models.Model):
blog = ForeignKeyField(Blog)
blog = ForeignKeyField(Blog)
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
3+)-.)(&)&/%(%1+%(
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
3+)-.)(&)&-*$./0
3+)-.)(&)&/%(%1+%(
>>> p.blog
>>> p.blog >>> 3+)-.)(&)&-*$./0
>>>b.post_set.all()
b.post_set.all()
3+)-.)(&)&/%(%1+%(
<Blog: Blog object>
<Blog: Blog object> 3+)-.)(&)&-*$./0
[<Post: Post object>, ...]
[<Post: Post object>, ...]
>>> p.blog >>> b.post_set.all()
>>> p.blog
<Blog: Blog object> >>> b.post_set.all()
[<Post: Post object>, ...]
<Blog: Blog object> [<Post: Post object>, ...]
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
76. !"#$%"&'()*"+%,
!"#$%"&'()*"+%,
!"#$%"&'()*"+%,
Relacionamentos Many-to-Many
ManyToManyField
ManyToManyField
class Post(models.Model):
class Post(models.Model):
// ManyToManyField
ManyToManyField
tags == ManyToManyField(Tag)
tags ManyToManyField(Tag)
m/ class Post(models.Model):
class Post(models.Model):
/
$
$
class Tag(models.Model):
class Tag(models.Model):
tags = ManyToManyField(Tag)
tags = ManyToManyField(Tag)
...
...
class Tag(models.Model):
n $
$
class Tag(models.Model):
...
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
...
3+)-.)(&)&/%(%1+%(
3+)-.)(&)&/%(%1+%( 3+)-.)(&)&-*$./0
3+)-.)(&)&-*$./0
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
!"#$%&'()$%(&*)&+,*)-.#/&0,(0,&*)(&./(1)/-.)(2
>>> p.tags.add(t1, t2)
>>> p.tags.add(t1, t2) >>> t.post_set.add(p1, p2)
>>> t.post_set.add(p1, p2)
>>> 3+)-.)(&)&/%(%1+%(
>>> p.tags.all()
p.tags.all() 3+)-.)(&)&-*$./0
>>> t.post_set.all()
>>> t.post_set.all()
3+)-.)(&)&/%(%1+%(...]
[<Tag: Tag object>, ...]
[<Tag: Tag object>,
3+)-.)(&)&-*$./0 ...]
[<Post: Post object>, ...]
[<Post: Post object>,
>>> p.tags.add(t1, t2)
>>> p.tags.add(t1, t2) >>> t.post_set.add(p1, p2)
>>> t.post_set.add(p1, p2)
>>> p.tags.all()
>>> p.tags.all() >>> t.post_set.all()
>>> t.post_set.all()
[<Tag: Tag object>, ...]
[<Tag: Tag object>, ...] [<Post: Post object>, ...]
[<Post: Post object>, Recife/PE
Residência de Reuso - 2011.1 - ...]
Saturday, May 21, 2011
77. !"#$%"&'()*"+%,
!"#$%"&'()*"+%,
!"#$%"&'()*"+%,
Ponteiros inversos
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
!"#$%&'(#)**'(#+%&),%(#-"./0)-$-#)*#+-"$).%#/"0).(%
1classclass Blog(models.Model):
class Blog(models.Model):
+ classBlog(models.Model):
Blog(models.Model):
++ ...
...
...
...
class Post(models.Model):
class Post(models.Model):
( classPost(models.Model):
(( n
class Post(models.Model):
blog = ForeignKeyField(Blog, related_name='posts')
blog = ForeignKeyField(Blog, related_name='posts')
blog = = ForeignKeyField(Blog, related_name='posts')
blog ForeignKeyField(Blog, related_name='posts')
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
!"#$%#&'#'()&)*")&
!"#$%#&'#'()&)*")& !"#$%#&'#'1*$.2/
!"#$%#&'#'1*$.2/
>>> p.blog
>>> p.blog >>> b.posts.all()
>>> b.posts.all()
>>> <Blog: Blog object>
p.blog
>>> p.blog >>> [<Post: Post object>, ...]
b.posts.all()
>>> b.posts.all()
<Blog: Blog object> [<Post: Post object>, ...]
<Blog: Blog object>
<Blog: Blog object> [<Post: Post object>, ...]
[<Post: Post object>, ...]
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
1-'"&%#2'3'#3'-"#$+4/.",'".%-"'3'0/&"#/,4#().5#/)#42$%/-4/
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
78. Laziness
!"#$%&''
!"#$%&''
#$%&'($)*+#$%'()*%$,%,-,&)+#./(%&)#(0'%.,#*1,(+,%$,%
Otimização!! Consulta só realizada quando necessário!
,&,$2+,%'3+,(,.%*'$%'3-,+'$4%5(%*#$%$26)2,(+,$%$2+)#&2'(,$7
#$%&'($)*+#$%'()*%$,%,-,&)+#./(%&)#(0'%.,#*1,(+,%$,%
! 8+,.#&2'(,$
,&,$2+,%'3+,(,.%*'$%'3-,+'$4%5(%*#$%$26)2,(+,$%$2+)#&2'(,$7
for p in Publisher.objects.all():
! 8+,.#&2'(,$
! 9*2&2(6 for p in Publisher.objects.all():
Publisher.objects.filter(country='USA')[0]
! 9*2&2(6
! 9,.2#*2:#&2;( Publisher.objects.filter(country='USA')[0]
<=#&>?@
! 9,.2#*2:#&2;(
• repr() <=#&>?@
[<Publisher: Publisher object>]
• len() !!!
repr() [<Publisher: Publisher object>]
len(Publisher.objects.all())
• list() !!!
len() len(Publisher.objects.all())
list(Publisher.objects.all())
Residência de Reuso - 2011.1 - Recife/PE
• bool()
list()
Saturday, May 21, 2011
list(Publisher.objects.all())
if Publisher.objects.filter(country='USA'):
79. Exercício 04
!"#$%&!'()*(+&"(*',(-(+&#./)*(&0&$(1(*(
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
84. !"#$%&'(%)*+,&%,-.
djang.contrib.admin
!"#$%&'(%)*+,&%,-.
Instalação 3/3
$ python manage.py syncdb
$ python manage.py syncdb
Creating table django_admin_log
Creating table django_admin_log
Installing index for admin.LogEntry model
Installing index for admin.LogEntry model
Acesse http://localhost:8000/admin
!"#$%&'$()*&+*,*&-(*,
!"#$%&'$()*&+*,*&-(*, Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
85. !"#$%&'(
Opa! Falta registrar os modelos
! "#$#%!''%$&'&%$&%(&)&*%&+%,-./0
! 1&2)&%3-4%5/$&+/,%,&*6)%78,8'+&,%$&,$&%&+%#$58)%.%
Criar o módulo admin.py
9&*58(&%9&*,/)#+8:#*%,-%#,9&;(/0 ser configurável!
Cada app deve ter o seu, pode
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)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
86. Exercício 04
!"#$%&'#(") Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
87. !"#$%$&'()*"+,-#.#$
!"#$%$&'()*"+,-#.#$
Forms
3 componentes
Widget
Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
!"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
Componente Visual
Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012
Widget TextInput <input type='text'...>
TextInput <input type='text'...>
TextInput <input type='text'...>
CheckboxInput <input type='checkbox'...>
CheckboxInput <input type='checkbox'...>
CheckboxInput <input type='checkbox'...>
Field
Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
/01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'
Campo Lógico
EmailField
Field EmailField
EmailField widget, initial, error, ...
IPAddressField widget, initial, error, ...
IPAddressField widget, initial, error, ...
IPAddressField
Form
Form !*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
Formulário em si
Form
Form !*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
!*(2+(3*(3&(9+&.36(3&(*%(:";#*.-;+"
ContactForm [nombre, email, telefono, mensaje, ...]
ContactForm [nombre, email, telefono, mensaje, ...]
ContactForm [nombre, email, telefono, mensaje, ...]
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
88. Criação de Formulário
Passo 1: Definição de um formulário forms.py
http://docs.djangoproject.com/en/dev/ref/forms/fields/
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
89. Criação de Formulário
Passo 2: Definição do template do Formulário
contato.html
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
90. Criação de Formulário
Passo 3: Definição da view do Formulário
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
91. !"#$%"&$'()*+,*$"
Criação de Formulário
!"#$%"&'()"*)+%+)',+-.#+/.01'$23)+'+&"/.+#+'+'/+#+'4.$-#'
Forms tem validação própria! Cool :D
#$-'5")%6-+)."'$&/).7.$1#"'61'%83"#"'clean_<fieldname>9
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
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
92. Forms a partir de Models
!"#$%&'&('#)#&*+&,"*+-% 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
."#$%/(0 class AuthorForm(forms.ModelForm):
class Meta:
model = Author
exclude = ('country',)
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
93. Exercício 04
Alguns truques agora...
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
96. !"##$%&'(%
Middleware
Permite incrementar a funcionalidade injetando fluxo de
!"#$%&'()*&$&#+'),)'$-./+)"/01)202$'&.31)40,1&$
execução em Django
5.&$#&$)/#&'*0$&/$&1$6.7"$2&$&7&+.+)8/$2&$970/:"
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
102. Deploying
Por o sistema em produção
VirtualEnv + PIP + Fabric
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
103. !"#$%&'()*
! "#$%&%#$%#'()*'+,&-%.)*$%*-)/*-(01%12)/*$%-*/(.%,)3
Virtualenv
! 4)$)*&1+5%'.+*6%#%*/7*87%9+*$%*-(01%12)/*%#*-)*:%1/(;#*<7%*#%'%/(.)
"#$%&%#$%#'()*'+,&-%.)*$%*-)/*-(01%12)/*$%-*/(.%,)3
! =(#*,(%$+*)*)'.7)-(>)1
! 4)$)*&1+5%'.+*6%#%*/7*87%9+*$%*-(01%12)/*%#*-)*:%1/(;#*<7%*#%'%/(.)
! =(#*,(%$+*)*,(91)1
=(#*,(%$+*)*)'.7)-(>)1
Projeto independente do sistema
! %.'333
=(#*,(%$+*)*,(91)1
Ou seja cada projeto com suas dependências
! %.'333
+#(&# específicas
+#(&# $ virtualenv --no-site-packages mi_entorno
$ virtualenv --no-site-packages mi_entorno
&+,*&#
$ source mi_entorno/bin/activate
Adeus dor de cabeça de migrar, atualizar, etc.
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
104. Pip
!"!
!"!
! "#$%&'()#(*+,-#%#$()#.($/0.&(12(34
Gerenciador de Pacotes
! ! 5#'6/%#(#$*#7/87+'(-9(87:#'&()#(;<=>?;<@<ABC(7&9(-9(./$%+)&()#(
"#$%&'()#(*+,-#%#$()#.($/0.&(12(34
! 5#'6/%#(#$*#7/87+'(-9(87:#'&()#(;<=>?;<@<ABC(7&9(-9(./$%+)&()#(
*+,-#%#$(+(/9$%+.+'D uma lista de requisitos (requirements)
Você pode criar
*+,-#%#$(+(/9$%+.+'D
para instalação automática! :D
4E+90&FF2D1D2
4E+90&FF2D1D2
*$G7&*01
*$G7&*01
H##)*+'$#'FFID2
H##)*+'$#'FFID2
$%'/*&0'+6FF2DJ
$%'/*&0'+6FF2DJ
"K:+'%L'+**#'FFMDN
"K:+'%L'+**#'FFMDN
pip install -E mi_entorno -r REQUIREMENTS
pip install -E mi_entorno -r REQUIREMENTS
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
105. !"#$%&
Fabric !"#$%&
““ Repetition leads to boredom, boredom to horrifying mistakes,
“Repetition leads to boredom, boredom to horrifying mistakes,
horrifying mistakes to God-I-wish-I-was-still-bored
Repetition leads to boredom, boredom to horrifying mistakes,
horrifying mistakes to God-I-wish-I-was-still-bored”
horrifying mistakes to God-I-wish-I-was-still-bored
'"#()*+,-
'"#()*+,-
env.user = "example"
env.hosts = ["example.com"]
def deploy():
env.user = "example"
run('svn up /home/example/')
env.hosts = ["example.com"]
sudo('/etc/init.d/lighttpd restart')
def deploy():
run('svn up /home/example/')
sudo('/etc/init.d/lighttpd restart')
./0
fabric deploy
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
107. %6*896(,%;6*8968.1<+,=>%
%?/,0'2(,/%
%?/,0'2(,/%*.3#:,(,%
django-registration
%?/,0'2(,/%*:.2,4%
%?:.0'1%
%?:.0.)(%
%?#622@./4%*!610,%
Sistema completo de cadastro de usuários
%?#622@./4%*!610,%4.1,%
%?#622@./4%/,2,(% DRY!!
%?#622@./4%/,2,(%*.1A/3%;(.+,1>
%?#622@./4%/,2,(%*.3#:,(,%
Instalação Copy and Paste
%?#622@./4%/,2,(%4.1,%
%?/,6*896(,%
!"#$%%&'(&)*+,(-./0%)&,/1.2(/)3%45610.7/,0'2(/68.1%
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
108. django-socialregistration
; <-2=&)80,'>2?192,'770
; @)(92:,0,'>2?,-2$
O django-registration só que anabolizado!
; (A'"98B?C0,9*--3B?-0)(!B?-#92'4
; D2(9&80,'>2?#98C9,(0?,-2?,-2(8'*+0)(!
Autenticação com Twitter, Facebook, oAuth, openID
Integração perfeita com django.contrib.auth
!"#$%%&'(!)*+,-.%/01!'2&#).#3'2%4502&-61-,'0789&'1(80:-2
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
109. django-piston
: ;</59,7./+;#5/5;*/,5/;=>?2;@ABCD)E
: ;F)G;DH*'E;'32(5E5*'I3 !"#$%&'()*+&$
Framework Django para construção de serviços RESTful
: ;B,/'5E'J5*'I3;5$
Fácil de instalar
: ;</59,7./+;#5/5;*/,5/;=>?2;@ABCD)E
: KBLMN;O=FPN;>G(!.3;>G*+E,N;QFP;---
: ;F)G;DH*'E;'32(5E5*'I3
Suporte para YAML, JSON, XML, etc.
: ;B,/'5E'J5*'I3;5$
: L=)(!
OAuth
: KBLMN;O=FPN;>G(!.3;>G*+E,N;QFP;---
: @,*.9,3454.;RRRRR : L=)(!
: @,*.9,3454.;RRRRR
!"#$%%&'(&)*+,(-./0%1,2#,/3%41530.6#'2(.3%7'+'%8.9,
!"#$%%&'(&)*+,(-./0%1,2#,/3%41530.6#'2(.3%7'+'%8.9,
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
110. Apenas uma ponta do iceberg
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
111. Lembre-se da comunidade!
http://python.org.br
http://djangobrasil.org
http://pug-pe.python.org.br
#django-br
#python-br
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
112. Trabalho da Semana
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
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
113. Referências
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
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
114. Bibliografia
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.
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
115. Apresentando
Marcel P. Caraciolo
@marcelcaraciolo
Residência RISE - 2011
Saturday, May 21, 2011
116. Exercício 01
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.
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
117. Exercício 05
Vamos criar a nossa interface administrativa para o nossos
modelos recém-criados
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011
118. Exercício 04
Vamos criar os modelos para Trabalho e Palestrante
Trabalho
usuario: User
titulo: String Palestrante
descricao: String 1. * * name
slides: File
status: Integer
Residência de Reuso - 2011.1 - Recife/PE
Saturday, May 21, 2011