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.

Henrique Bastos

October 02, 2013
Tweet

More Decks by Henrique Bastos

Other Decks in Programming

Transcript

  1. 3

  2. $  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
  3. repo/    manage.py    myproject/    __init__.py    settings.py  

     urls.py    wsgi.py Estrutura do Projeto 14
  4. $  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
  5. 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
  6. 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
  7. $  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
  8. 1. Request Middleware 2. Url Resolve 3. View Middleware 4.

    View 5. Template Response Middleware 6. Response Middleware Request Handler 20
  9. URLConf Um módulo que contém uma variável urlpatterns que referencia

    uma sequência de rotas associadas à views. 22
  10. 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
  11. 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
  12. Views Um callable que recebe uma instância de HttpRequest e

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

    HttpResponse('Opa!') A view mais simples do mundo. 28
  14. 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
  15. 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
  16. Form Fields BooleanField CharField ChoiceField TypedChoiceField DateField DateTimeField DecimalField EmailField

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

    DateInput DateTimeInput TimeInput CheckboxInput Select NullBooleanSelect SelectMultiple RadioInput RadioFieldRenderer RadioSelect CheckboxSelectMultiple MultiWidget 33
  18. 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
  19. 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
  20. 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
  21. # 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
  22. 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
  23. 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
  24. 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
  25. $  manage  shell >>>  from  myproject.myapp.models  import  Subscription >>>  s

     =  Subscription( ...          name="Henrique  Bastos", ...          cpf="12345678901", ...          email="[email protected]", ...          phone="21-­‐9618-­‐6180") >>>  s.save() 47
  26. $  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
  27. >>>  #  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'[email protected]' 50
  28. 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
  29. 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
  30. <!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
  31. <!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
  32. <!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
  33. # 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
  34. 67