Share
Embed
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
Transcript
68 slides
-
“ ” Django é o framework web para perfeccionistas com
prazos. #jabá 5 -
“ ” Django é o seu banco de dados na
web. #sqn 7 -
$ 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 -
$ 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 -
repo/ manage.py myproject/ __init__.py settings.py
urls.py wsgi.py Estrutura do Projeto 14 -
$ 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 -
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 -
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 -
$ 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 -
1. Request Middleware 2. Url Resolve 3. View Middleware 4.
View 5. Template Response Middleware 6. Response Middleware Request Handler 20 -
URLConf Um módulo que contém uma variável urlpatterns que referencia
uma sequência de rotas associadas à views. 22 -
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 -
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 -
Views Um callable que recebe uma instância de HttpRequest e
retorna uma instância de HttpResponse. 27 -
# coding: utf-8 from django.http import HttpResponse def myview(request): return
HttpResponse('Opa!') A view mais simples do mundo. 28 -
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 -
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 -
Form Fields BooleanField CharField ChoiceField TypedChoiceField DateField DateTimeField DecimalField EmailField
FileField FilePathField FloatField ImageField IntegerField IPAddressField MultipleChoiceField NullBooleanField RegexField SlugField TimeField URLField 32 -
Form Widgets Input TextInput PasswordInput HiddenInput MultipleHiddenInput FileInput ClearableFileInput Textarea
DateInput DateTimeInput TimeInput CheckboxInput Select NullBooleanSelect SelectMultiple RadioInput RadioFieldRenderer RadioSelect CheckboxSelectMultiple MultiWidget 33 -
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 -
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 -
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 -
# 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 -
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 -
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 -
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 -
$ 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 -
$ 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 -
>>> # 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 -
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 -
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 -
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 -
<!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 -
<!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 -
<!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 -
# 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