introdução ao django

Post on 19-May-2015

8.097 Views

Category:

Technology

1 Downloads

Preview:

Click to see full reader

DESCRIPTION

Curso de Django para a Residência De Reuso pela startup RISE 21/05/2011

TRANSCRIPT

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/

DRYDon’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 - Views12

Aplicações

Deve fazer uma coisa, e fazer direito

Se a descrição de sua aplicação for maior que umalinha, 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çãoAplicaçõ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-22304525

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/downloadpython 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 djangoTraceback (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 djangoTraceback (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 djangoTraceback (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 djangoTraceback (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 HttpResponsefrom 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 HttpResponsefrom 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 HttpResponsefrom 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 HttpResponsefrom 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:

TemplateString 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 HttpResponsefrom django.template import Template, Contextfrom 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 HttpResponsefrom django.template import Template, Contextfrom 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 HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom 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 HttpResponsefrom django.template.loader import get_templatefrom django.template import Contextfrom 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_responsefrom 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 syncdbCreating table auth_permissionCreating table auth_groupCreating table auth_userCreating table auth_messageCreating table django_content_typeCreating table django_sessionCreating table django_siteCreating 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): yesUsername (Leave blank to use 'neo'): admin E-mail address: user@example.comPassword: Password (again): Superuser created successfully.Installing index for auth.Permission modelInstalling index for auth.Message modelInstalling 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.id52>>> p.name = 'Apress Publishing'>>> p.save()

o.save()

!

!"#$%&

>>> Publisher.objects.all().update(country='USA')2

>>> ...

>>> p.id52>>> 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.id52>>> p.delete()

o.delete()

queryset.delete()

!

"

!"#"$"

>>> ps = Publisher.objects.all()>>> ps.delete()

>>> ...

>>> p.id52>>> 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

FieldCampo Lógico

Form

!"#$%$&'()*"+,-#.#$

Widget !"#$"%&%'&()'$+#"(&)*+,-.&%'&(-(/012

TextInput

CheckboxInput

<input type='text'...>

<input type='checkbox'...>

Field /01',#(3&(*%(4-#$"5(-6"4+-3"(-(*%(7+38&'

EmailField

IPAddressFieldwidget, 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

IPAddressFieldwidget, 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

IPAddressFieldwidget, 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 entidadesO sistema deve ter controle de acesso

(ver django-registration)

Modelagem vocês decidemApresentar 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. Caraciolocaraciol@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: Usertitulo: Stringdescricao: Stringslides: Filestatus: Integer

namePalestrante

*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

top related