Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Um raio-x do Django

Um raio-x do Django

Que o Django é sensacional, todo mundo já sabe. Mas do que é feito o Django?

Com frequência, muita gente acaba focando em models e views, esquecendo dos Urconf, Managers, ModelFields, Querysets, Forms, FormFields, Templates, Filters, Tags, Middleware, contrib apps, etc.

Conhecer as partes do framework é essencial para conseguir usufruir de todo o poder que a ferramenta propicia e escrever menos código.

Nesta palestra mapearemos os elementos que compõe o framework apontando como eles se relacionam. Conhecendo melhor o terreno, aqueles que estiverem se familiarizando com Django poderão começar com o pé direito e quem já está experimentando a ferramenta poderá organizar melhor a sua aplicação.

D47e5a6a94e793ad1a1c315d6ab63877?s=128

Henrique Bastos

October 02, 2013
Tweet

Transcript

  1. Um raio-x do Django Henrique Bastos PythonBrasil[9] 1

  2. henrique@bastos.net @henriquebastos http://henriquebastos.net 2

  3. 3

  4. Django 4

  5. “ ” Django é o framework web para perfeccionistas com

    prazos. #jabá 5
  6. Models Django 6

  7. “ ” Django é o seu banco de dados na

    web. #sqn 7
  8. Top Down vs Bottom Up 8

  9. World Wide What? 9

  10. HttpRequest HttpResponse 10

  11. $  curl  -­‐iv  http://welcometothedjango.com.br GET  /  HTTP/1.1 User-­‐Agent:  curl/7.19.7  (universal-­‐apple-­‐darwin10.0)

     libcurl/7.19.7 Host:  welcometothedjango.com.br Accept:  */*   HTTP Request 11
  12. $  curl  -­‐i  http://welcometothedjango.com.br/ HTTP/1.1  200  OK Server:  nginx/0.7.65 Content-­‐Type:

     text/html;  charset=utf-­‐8 Cache-­‐Control:  max-­‐age=600 <html> <head>        <title>Welcome  to  the  Django  |  Aprendendo  Python  e  Django  na  prática!</title>    <link  rel="stylesheet"  type="text/css"  href="/static/css/screen.css"  media="screen"  /> </head> <body>    <h1>Welcome  to  the  Django</h1> </body> </html> HTTP Response 12
  13. django-admin.py startproject myproject Projeto Django 13

  14. repo/    manage.py    myproject/    __init__.py    settings.py  

     urls.py    wsgi.py Estrutura do Projeto 14
  15. $  python  manage.py Usage:  manage.py  subcommand  [options]  [args] Options:  

     -­‐v  VERBOSITY,  -­‐-­‐verbosity=VERBOSITY                                                Verbosity  level;  0=minimal  output,  1=normal  output,                                                2=verbose  output,  3=very  verbose  output    -­‐-­‐settings=SETTINGS      The  Python  path  to  a  settings  module,  e.g.                                                "myproject.settings.main".  If  this  isn't  provided,  the                                                DJANGO_SETTINGS_MODULE  environment  variable  will  be                                                used.    -­‐-­‐pythonpath=PYTHONPATH                                                A  directory  to  add  to  the  Python  path,  e.g.                                                "/home/djangoprojects/myproject".    -­‐-­‐traceback                      Print  traceback  on  exception    -­‐-­‐version                          show  program's  version  number  and  exit    -­‐h,  -­‐-­‐help                        show  this  help  message  and  exit Type  'manage.py  help  <subcommand>'  for  help  on  a  specific  subcommand. Available  subcommands: ... 15
  16. Um pacote Python que contém um módulo models.py Django App

    16
  17. repo/    manage.py    myproject/    __init__.py    settings.py  

     urls.py    wsgi.py    myapp/        __init__.py        models.py        tests.py        views.py Estrutura da App 17
  18. INSTALLED_APPS  =  (        'django.contrib.auth',      

     'django.contrib.contenttypes',        'django.contrib.sessions',        'django.contrib.sites',        'django.contrib.messages',        'django.contrib.staticfiles',        #  Uncomment  the  next  line  to  enable  the  admin:        #  'django.contrib.admin',        #  Uncomment  the  next  line  to  enable  admin  documentation:        #  'django.contrib.admindocs',        'myproject.myapp', ) myproject/settings.py 18
  19. $  manage  runserver Validating  models... 0  errors  found Django  version

     1.5.2,  using  settings  'myproject.settings' Development  server  is  running  at  http://127.0.0.1:8000/ Quit  the  server  with  CONTROL-­‐C. 19
  20. 1. Request Middleware 2. Url Resolve 3. View Middleware 4.

    View 5. Template Response Middleware 6. Response Middleware Request Handler 20
  21. Url Resolve 21

  22. URLConf Um módulo que contém uma variável urlpatterns que referencia

    uma sequência de rotas associadas à views. 22
  23. urlpatterns  =  patterns('',        url('^time/plus/1/$',  one_hour_ahead),    

       url('^time/plus/2/$',  two_hours_ahead),        ...        url('^time/plus/24/$',  tons_hours_ahead), ) Exemplo 23
  24. urlpatterns  =  patterns('',        url('^time/plus/(\d{1,2})/$',  time_ahead), ) Bem

    melhor... 24
  25. Expressões Regulares http://docs.python.org/library/re.html#re-syntax http://www.pythonregex.com/ 25

  26. URL Resolvers $  manage  shell >>> from django.core.urlresolvers import reverse,

    resolve >>> resolve('/inscricao/1/') (<function myproject.myapp.views.myview>, ('1',), {}) >>> reverse('myapp:detail', args=[1]) '/inscricao/1/' 26
  27. Views Um callable que recebe uma instância de HttpRequest e

    retorna uma instância de HttpResponse. 27
  28. # coding: utf-8 from django.http import HttpResponse def myview(request): return

    HttpResponse('Opa!') A view mais simples do mundo. 28
  29. Anti-patterns Views grandes; Conversões de dados na view; Pilhas de

    decoradores; Uso de funções auxiliares que instanciam o HttpResponse; Contextos de templates gigantes; 29
  30. Forms Muito além de formulários... 30

  31. Arquitetura dos Forms Forms Responsável pelo pipeline de validação Fields

    Valida dados da requisição e os converte para tipos Python Widgets Representa o valor do field em html. 31
  32. Form Fields BooleanField CharField ChoiceField TypedChoiceField DateField DateTimeField DecimalField EmailField

    FileField FilePathField FloatField ImageField IntegerField IPAddressField MultipleChoiceField NullBooleanField RegexField SlugField TimeField URLField 32
  33. Form Widgets Input TextInput PasswordInput HiddenInput MultipleHiddenInput FileInput ClearableFileInput Textarea

    DateInput DateTimeInput TimeInput CheckboxInput Select NullBooleanSelect SelectMultiple RadioInput RadioFieldRenderer RadioSelect CheckboxSelectMultiple MultiWidget 33
  34. Anatomia de um FormField 34

  35. class IntegerField(Field): default_error_messages = { 'invalid': _(u'Enter a whole number.'),

    'max_value': _(u'Ensure this value is less than or equal to %(limit_value)s.'), 'min_value': _(u'Ensure this value is greater than or equal to %(limit_value)s.'), } def __init__(self, max_value=None, min_value=None, *args, **kwargs): super(IntegerField, self).__init__(*args, **kwargs) if max_value is not None: self.validators.append(validators.MaxValueValidator(max_value)) if min_value is not None: self.validators.append(validators.MinValueValidator(min_value)) def to_python(self, value): """ Validates that int() can be called on the input. Returns the result of int(). Returns None for empty values. """ value = super(IntegerField, self).to_python(value) if value in validators.EMPTY_VALUES: return None if self.localize: value = formats.sanitize_separators(value) try: value = int(str(value)) except (ValueError, TypeError): raise ValidationError(self.error_messages['invalid']) return value 35
  36. Anatomia de um Widget 36

  37. class Textarea(Widget): def __init__(self, attrs=None): # The 'rows' and 'cols'

    attrs are required for HTML correctness. default_attrs = {'cols': '40', 'rows': '10'} if attrs: default_attrs.update(attrs) super(Textarea, self).__init__(default_attrs) def render(self, name, value, attrs=None): if value is None: value = '' final_attrs = self.build_attrs(attrs, name=name) return format_html('<textarea{0}>\r\n{1}</textarea>', flatatt(final_attrs), force_text(value)) 37
  38. Bounded SubscriptionForm(request.POST) ou seja, com dados vs Unbounded SubscriptionForm() ou

    seja, sem dados 38
  39. Dentro do form.is_valid() 1. Se Form for bounded... 2. Form

    full_clean() 3. Para cada Field é executado: 3.1. clean() do Field 3.2. validators do Field 3.3. método clean_* se existir no Form 4. Form clean() 5. errors ou cleaned_data 39
  40. Models 40

  41. # coding: utf-8 from django.db import models class Subscription(models.Model): name

    = models.CharField(max_length=100) cpf = models.CharField(max_length=11) email = models.EmailField() phone = models.CharField(max_length=20, blank=True) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['created_at'] def __unicode__(self): return self.name Model 41
  42. CREATE  TABLE  "myapp_subscription"  (        "id"  integer  NOT

     NULL  PRIMARY  KEY,        "name"  varchar(100)  NOT  NULL,        "cpf"  varchar(11)  NOT  NULL  UNIQUE,        "email"  varchar(75)  NOT  NULL  UNIQUE,        "phone"  varchar(20)  NOT  NULL,        "created_at"  datetime  NOT  NULL ); 42
  43. Cada um no seu quadrado >>>  type(Subscription) ...  <class  'django.db.models.base.ModelBase'>

    >>>  type(Subscription(...)) ...  <class  'myproject.myapp.models.Subscription' >>>  type(Subscription.objects) ...  <class  'django.db.models.manager.Manager'> >>>  type(Subscription.objects.all()) ...  <class  'django.db.models.query.QuerySet'> 43
  44. Cada um no seu quadrado >>>  Subscription ...  Descreve  a

     estrutura  de  uma  tabela >>>  Subscription(...) ...  Corresponde  à  uma  linha  da  tabela >>>  Subscription.objects ...  Manipula  todas  as  linhas  da  tabela >>>  Subscription.objects.all() ...  Acumula  estados  que  serão  usados  pelo  ORM  para ...  compilar  uma  query  SQL 44
  45. Model Fields Correlacionam atributos do modelo com colunas da tabela

    45
  46. Insert e Update 46

  47. $  manage  shell >>>  from  myproject.myapp.models  import  Subscription >>>  s

     =  Subscription( ...          name="Henrique  Bastos", ...          cpf="12345678901", ...          email="henrique@bastos.net", ...          phone="21-­‐9618-­‐6180") >>>  s.save() 47
  48. $  manage  shell >>>  s.id ...  1 >>>  s.pk  #

     property  que  neste  caso  retorna  s.id ...  1 >>>  s.phone="234-­‐5678" >>>  s.save()  #  update,  pois  s  já  tem  id 48
  49. Seleção e Filtro 49

  50. >>>  #  instancia  um  QuerySet >>>  qs  =  Subscription.objects.all()  

    >>>  #  realiza  a  query  no  banco  apenas  quando  necessário >>>  print  qs [Henrique  Bastos] >>>  qs[0].email  #  retorna  o  email  do  1º  elemento u'henrique@bastos.net' 50
  51. Selecionando 1 único objeto >>>  s  =  Subscription.objects.get(name__contains="Bas") >>>  s.phone

    u'21-­‐9618-­‐6180' 51
  52. Filtros >>>  qs  =  Subscription.objects.filter(name__startswith="H") >>>  qs[0].phone u'21-­‐9618-­‐6180' 52

  53. Encadeamento >>>  qs  =  Subscription.objects.all() >>>  qs  =  qs.filter(name__contains="Bas") >>>

     qs  =  qs.order_by("name") Subscription.objects.filter(name__contains="Bas").order_by("name") 53
  54. Field Lookup exact iexact contains icontains in gt gte lt

    lte startswith istartswith endswith iendswith ... https://docs.djangoproject.com/en/1.5/topics/db/queries/#field-lookups 54
  55. Ordenação #  Ascendente Subscription.objects.order_by("name") #  Descendente Subscription.objects.order_by("-­‐name") 55

  56. Slicing limita a sua query Subscription.objects.all()[0] Subscription.objects.all()[0:2] Subscription.objects.all()[-­‐1]  #  NOT

    56
  57. Subscription.objects.all().update(name="Outro  Nome") Subscription.objects.all().delete() Update e Delete múltiplo 57

  58. abstract app_label db_table db_tablespace ordering proxy unique_together verbose_name verbose_name_plural ...

    Meta https://docs.djangoproject.com/en/1.5/ref/models/options/ 58
  59. Templates 59

  60. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html> <head><title>Myproject</title></head> <body> <img

     src="{{  STATIC_URL  }}img/logo.png"  /> <h1>Parabéns  {{  subscription.name  }}!</h1> <p> Sua  inscrição  foi  realizada  em   {{  subscription.created_at|date:"d/m/Y"  }}. </p> <p> Em  breve,  alguém  entrará  em  contato  pelo {%  if  subscription.phone  %} telefone  {{  subscription.phone  }}. {%  else  %} e-­‐mail  {{  subscription.email  }}. {%  endif  %} </p>                   </body> </html> Template Variables 60
  61. {{ subscription.name }} 1. subscription["name"] 2. subscription.name 3. subscription.name() O

    ponto-chave 61
  62. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html> <head><title>Myproject</title></head> <body> <img

     src="{{  STATIC_URL  }}img/logo.png"  /> <h1>Parabéns  {{  subscription.name  }}!</h1> <p> Sua  inscrição  foi  realizada  em   {{  subscription.created_at|date:"d/m/Y"  }}. </p> <p> Em  breve,  alguém  entrará  em  contato  pelo {%  if  subscription.phone  %} telefone  {{  subscription.phone  }}. {%  else  %} e-­‐mail  {{  subscription.email  }}. {%  endif  %} </p>                   </body> </html> Template Filters 62
  63. {{  subscription.created_at|date:"d/m/Y"  }} {{  text|escape|linebreaks  }} {{  text|truncatewords:"30"  }} 63

  64. <!DOCTYPE  HTML  PUBLIC  "-­‐//W3C//DTD  HTML  4.01//EN"> <html> <head><title>Myproject</title></head> <body> <img

     src="{{  STATIC_URL  }}img/logo.png"  /> <h1>Parabéns  {{  subscription.name  }}!</h1> <p> Sua  inscrição  foi  realizada  em   {{  subscription.created_at|date:"d/m/Y"  }}. </p> <p> Em  breve,  alguém  entrará  em  contato  pelo {%  if  subscription.phone  %} telefone  {{  subscription.phone  }}. {%  else  %} e-­‐mail  {{  subscription.email  }}. {%  endif  %} </p>                   </body> </html> Template Tags 64
  65. # coding: utf-8 from django.http import HttpResponse from django.template import

    loader, RequestContext def homepage(request): t = loader.get_template('index.html') c = RequestContext(request) content = t.render(c) return HttpResponse(content) Uso de Templates 65
  66. Include vs Extends 66

  67. 67

  68. https://docs.djangoproject.com/en/1.5/ref/templates/builtins/ 68