SlideShare a Scribd company logo
1 of 110
DESENVOLVIMENTO
WEB USANDO
DJANGO
YURIMALHEIROS@
YURIMALHEIROS
@GMAIL.COM
TECNOLOGIA
TECNOLOGIA?
TECNOLOGIA?
SIMPLE IS
BETTER THAN
COMPLEX
FRAMEWORKS
”
“SE VI MAIS
LONGE FOI POR
ESTAR SOBRE
OS OMBROS
DE GIGANTES
UM POUCO DE
HISTÓRIA...
MODEL
VIEW
CONTROLLER
MODEL
TEMPLATE
CONTROLLER
MODEL
TEMPLATE
VIEW
CODIFICANDO
django-admin startproject mymusic
mymusic
manage.py
settings.py
urls.py
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': 'db.sqlite',
'USER': '‘,
'PASSWORD': '‘,
'HOST': '‘,
'PORT': '‘, }
}
settings.py
manage.py startapp collection
collection
models.py
tests.py
views.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
from django.db import models
class Album(models.Model):
artist = models.CharField(max_length=200)
name = models.CharField(max_length=200)
year = models.IntegerField()
cover = models.URLField(verify_exists=False,
blank=True)
def __unicode__(self):
return "%s by %s" % (self.name, self.artist)
collection/models.py
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'collection',
)
settings.py
manage.py syncdb
add/
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^add/$', collection_views.add),
)
urls.py
from django.forms import ModelForm
from collection.models import Album
class AlbumForm(ModelForm):
class Meta:
model = Album
exclude = (‘cover’,)
collection/forms.py
from django.forms import ModelForm
from collection.models import Album
class AlbumForm(ModelForm):
class Meta:
model = Album
exclude = (‘cover’,)
collection/forms.py
from django.forms import ModelForm
from collection.models import Album
class AlbumForm(ModelForm):
class Meta:
model = Album
exclude = (‘cover’,)
collection/forms.py
from django.forms import ModelForm
from collection.models import Album
class AlbumForm(ModelForm):
class Meta:
model = Album
exclude = (‘cover’,)
collection/forms.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
def add(request):
if request.method == 'POST':
form = AlbumForm(data=request.POST)
if form.is_valid():
album = Album()
album.name = form.cleaned_data['name']
album.artist =
form.cleaned_data['artist']
album.year = form.cleaned_data['year']
album.cover = get_cover_url(album.artist,
album.name)
album.save()
collection/views.py
else:
form = AlbumForm()
return render_to_response('add.html', {'form' :
form}, context_instance=RequestContext(request))
collection/views.py
else:
form = AlbumForm()
return render_to_response('add.html', {'form' :
form}, context_instance=RequestContext(request))
collection/views.py
else:
form = AlbumForm()
return render_to_response('add.html', {'form' :
form}, context_instance=RequestContext(request))
collection/views.py
else:
form = AlbumForm()
return render_to_response('add.html', {'form' :
form}, context_instance=RequestContext(request))
collection/views.py
else:
form = AlbumForm()
return render_to_response('add.html', {'form' :
form}, context_instance=RequestContext(request))
collection/views.py
settings.py
import os
PROJECT_PATH =
os.path.dirname(os.path.abspath(__file__))
TEMPLATE_DIRS = (
os.path.join(PROJECT_PATH, 'templates'),
)
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
<form action="." method="post"
enctype="multipart/form-data">
{% csrf_token %}
{% for field in form %}
<div class="fieldWrapper">
{{ field.errors }}
{{ field.label_tag }}: {{ field }}
</div>
{% endfor %}
<p><button type="submit">Adicionar</button></p>
</form>
templates/add.html
manage.py runserver
/
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
)
urls.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
def index(request):
albums = Album.objects.all().order_by('name')
return render_to_response('index.html', {'albums'
: albums}, context_instance=RequestContext(request))
collection/views.py
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
</p>
{% endfor %}
templates/index.html
delete/
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
from django.conf.urls.defaults import *
from collection import views as collection_views
urlpatterns = patterns('',
url(r'^$', collection_views.index,
name='album_index'),
url(r'^add/$', collection_views.add),
url(r'^delete/(?P<album_id>d+)/$',
collection_views.delete,
name='album_delete'),
)
urls.py
def delete(request, album_id):
album = Album.objects.get(pk=album_id)
album.delete()
return redirect('album_index')
collection/views.py
def delete(request, album_id):
album = Album.objects.get(pk=album_id)
album.delete()
return redirect('album_index')
collection/views.py
def delete(request, album_id):
album = Album.objects.get(pk=album_id)
album.delete()
return redirect('album_index')
collection/views.py
def delete(request, album_id):
album = Album.objects.get(pk=album_id)
album.delete()
return redirect('album_index')
collection/views.py
{% for album in albums %}
<p>
{% if album.cover %}
<img src="{{album.cover}}" />
{% endif %}
{{album.name}}<br />
{{album.artist}}<br />
<a href={% url album_delete album.pk
%}>apagar</a>
</p>
{% endfor %}
templates/index.html
GITHUB.COM/
YURIMALHEIROS
BÁSICO
PYTHON
FERRAMENTA
COMUNIDADE
BOA ESCOLHA :)
DÚVIDAS?

More Related Content

What's hot

全裸でワンライナー(仮)
全裸でワンライナー(仮)全裸でワンライナー(仮)
全裸でワンライナー(仮)Yoshihiro Sugi
 
Five things for you - Yahoo developer offers
Five things for you - Yahoo developer offersFive things for you - Yahoo developer offers
Five things for you - Yahoo developer offersChristian Heilmann
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackVic Metcalfe
 
The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88Mahmoud Samir Fayed
 
Make your own wp cli command in 10min
Make your own wp cli command in 10minMake your own wp cli command in 10min
Make your own wp cli command in 10minIvelina Dimova
 
Swift - Modern & Expressive, or Magical Unicorn?
Swift  - Modern & Expressive, or Magical Unicorn?Swift  - Modern & Expressive, or Magical Unicorn?
Swift - Modern & Expressive, or Magical Unicorn?Mike Jones
 
The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184Mahmoud Samir Fayed
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPDan Jesus
 
WordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPandrewnacin
 
Templates don’t need to break the browser by Nikolas Martens
Templates don’t need to break the browser by Nikolas Martens  Templates don’t need to break the browser by Nikolas Martens
Templates don’t need to break the browser by Nikolas Martens Codemotion
 
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017Codemotion
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and ProfitOlaf Alders
 
Phoenix for laravel developers
Phoenix for laravel developersPhoenix for laravel developers
Phoenix for laravel developersLuiz Messias
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”apostlion
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First WidgetChris Wilcoxson
 
Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)garux
 
SCBCN17 - El camino hacia la programación declarativa
SCBCN17 - El camino hacia la programación declarativaSCBCN17 - El camino hacia la programación declarativa
SCBCN17 - El camino hacia la programación declarativaGerard Madorell
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askAndrea Giuliano
 

What's hot (20)

全裸でワンライナー(仮)
全裸でワンライナー(仮)全裸でワンライナー(仮)
全裸でワンライナー(仮)
 
Five things for you - Yahoo developer offers
Five things for you - Yahoo developer offersFive things for you - Yahoo developer offers
Five things for you - Yahoo developer offers
 
An Elephant of a Different Colour: Hack
An Elephant of a Different Colour: HackAn Elephant of a Different Colour: Hack
An Elephant of a Different Colour: Hack
 
The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88The Ring programming language version 1.3 book - Part 36 of 88
The Ring programming language version 1.3 book - Part 36 of 88
 
Make your own wp cli command in 10min
Make your own wp cli command in 10minMake your own wp cli command in 10min
Make your own wp cli command in 10min
 
Swift - Modern & Expressive, or Magical Unicorn?
Swift  - Modern & Expressive, or Magical Unicorn?Swift  - Modern & Expressive, or Magical Unicorn?
Swift - Modern & Expressive, or Magical Unicorn?
 
The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184The Ring programming language version 1.5.3 book - Part 46 of 184
The Ring programming language version 1.5.3 book - Part 46 of 184
 
Simple swing programs
Simple swing programsSimple swing programs
Simple swing programs
 
Frameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHPFrameworks da nova Era PHP FuelPHP
Frameworks da nova Era PHP FuelPHP
 
WordPress 3.1 at DC PHP
WordPress 3.1 at DC PHPWordPress 3.1 at DC PHP
WordPress 3.1 at DC PHP
 
Templates don’t need to break the browser by Nikolas Martens
Templates don’t need to break the browser by Nikolas Martens  Templates don’t need to break the browser by Nikolas Martens
Templates don’t need to break the browser by Nikolas Martens
 
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017
Templating you're doing it wrong - Nikolas Martens - Codemotion Amsterdam 2017
 
(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit(Ab)Using the MetaCPAN API for Fun and Profit
(Ab)Using the MetaCPAN API for Fun and Profit
 
Phoenix for laravel developers
Phoenix for laravel developersPhoenix for laravel developers
Phoenix for laravel developers
 
RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”RubyBarCamp “Полезные gems и plugins”
RubyBarCamp “Полезные gems и plugins”
 
Building Your First Widget
Building Your First WidgetBuilding Your First Widget
Building Your First Widget
 
Vcs17
Vcs17Vcs17
Vcs17
 
Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)Communities - Perl edition (RioJS)
Communities - Perl edition (RioJS)
 
SCBCN17 - El camino hacia la programación declarativa
SCBCN17 - El camino hacia la programación declarativaSCBCN17 - El camino hacia la programación declarativa
SCBCN17 - El camino hacia la programación declarativa
 
Everything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to askEverything you always wanted to know about forms* *but were afraid to ask
Everything you always wanted to know about forms* *but were afraid to ask
 

Similar to Django Web Dev

Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Fabien Potencier
 
Intro to Pylons / Pyramid
Intro to Pylons / PyramidIntro to Pylons / Pyramid
Intro to Pylons / PyramidEric Paxton
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkJeremy Kendall
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в DjangoMoscowDjango
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneRafael Felix da Silva
 
Django#101 – All You Need to Know for Getting Started
Django#101 – All You Need to Know for Getting StartedDjango#101 – All You Need to Know for Getting Started
Django#101 – All You Need to Know for Getting StartedPankamol Srikaew
 
Chapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsChapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsVincent Chien
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django IntroductionGanga Ram
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Luka Zakrajšek
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to DjangoJoaquim Rocha
 

Similar to Django Web Dev (20)

Django
DjangoDjango
Django
 
Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)Be RESTful (Symfony Camp 2008)
Be RESTful (Symfony Camp 2008)
 
Intro to Pylons / Pyramid
Intro to Pylons / PyramidIntro to Pylons / Pyramid
Intro to Pylons / Pyramid
 
Keeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro FrameworkKeeping it Small: Getting to know the Slim Micro Framework
Keeping it Small: Getting to know the Slim Micro Framework
 
Django quickstart
Django quickstartDjango quickstart
Django quickstart
 
Django Heresies
Django HeresiesDjango Heresies
Django Heresies
 
Class Based Generic Views в Django
Class Based Generic Views в DjangoClass Based Generic Views в Django
Class Based Generic Views в Django
 
Aplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com BackboneAplicacoes dinamicas Rails com Backbone
Aplicacoes dinamicas Rails com Backbone
 
Backbone Basics with Examples
Backbone Basics with ExamplesBackbone Basics with Examples
Backbone Basics with Examples
 
Django#101 – All You Need to Know for Getting Started
Django#101 – All You Need to Know for Getting StartedDjango#101 – All You Need to Know for Getting Started
Django#101 – All You Need to Know for Getting Started
 
Django crush course
Django crush course Django crush course
Django crush course
 
Lithium Best
Lithium Best Lithium Best
Lithium Best
 
Chapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfsChapter 8- Advanced Views and URLconfs
Chapter 8- Advanced Views and URLconfs
 
A Basic Django Introduction
A Basic Django IntroductionA Basic Django Introduction
A Basic Django Introduction
 
Django Class-based views (Slovenian)
Django Class-based views (Slovenian)Django Class-based views (Slovenian)
Django Class-based views (Slovenian)
 
Django
DjangoDjango
Django
 
Django Vs Rails
Django Vs RailsDjango Vs Rails
Django Vs Rails
 
Introduction to Django
Introduction to DjangoIntroduction to Django
Introduction to Django
 
pyscript_django.pdf
pyscript_django.pdfpyscript_django.pdf
pyscript_django.pdf
 
Django
DjangoDjango
Django
 

Django Web Dev

  • 6.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 16. ” “SE VI MAIS LONGE FOI POR ESTAR SOBRE OS OMBROS DE GIGANTES
  • 17.
  • 25. DATABASES = { 'default': { 'ENGINE': 'django.db.backends.sqlite3', 'NAME': 'db.sqlite', 'USER': '‘, 'PASSWORD': '‘, 'HOST': '‘, 'PORT': '‘, } } settings.py
  • 28. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 29. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 30. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 31. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 32. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 33. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 34. from django.db import models class Album(models.Model): artist = models.CharField(max_length=200) name = models.CharField(max_length=200) year = models.IntegerField() cover = models.URLField(verify_exists=False, blank=True) def __unicode__(self): return "%s by %s" % (self.name, self.artist) collection/models.py
  • 37. add/
  • 38. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^add/$', collection_views.add), ) urls.py
  • 39. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^add/$', collection_views.add), ) urls.py
  • 40. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^add/$', collection_views.add), ) urls.py
  • 41. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^add/$', collection_views.add), ) urls.py
  • 42. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^add/$', collection_views.add), ) urls.py
  • 43. from django.forms import ModelForm from collection.models import Album class AlbumForm(ModelForm): class Meta: model = Album exclude = (‘cover’,) collection/forms.py
  • 44. from django.forms import ModelForm from collection.models import Album class AlbumForm(ModelForm): class Meta: model = Album exclude = (‘cover’,) collection/forms.py
  • 45. from django.forms import ModelForm from collection.models import Album class AlbumForm(ModelForm): class Meta: model = Album exclude = (‘cover’,) collection/forms.py
  • 46. from django.forms import ModelForm from collection.models import Album class AlbumForm(ModelForm): class Meta: model = Album exclude = (‘cover’,) collection/forms.py
  • 47. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 48. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 49. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 50. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 51. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 52. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 53. def add(request): if request.method == 'POST': form = AlbumForm(data=request.POST) if form.is_valid(): album = Album() album.name = form.cleaned_data['name'] album.artist = form.cleaned_data['artist'] album.year = form.cleaned_data['year'] album.cover = get_cover_url(album.artist, album.name) album.save() collection/views.py
  • 54. else: form = AlbumForm() return render_to_response('add.html', {'form' : form}, context_instance=RequestContext(request)) collection/views.py
  • 55. else: form = AlbumForm() return render_to_response('add.html', {'form' : form}, context_instance=RequestContext(request)) collection/views.py
  • 56. else: form = AlbumForm() return render_to_response('add.html', {'form' : form}, context_instance=RequestContext(request)) collection/views.py
  • 57. else: form = AlbumForm() return render_to_response('add.html', {'form' : form}, context_instance=RequestContext(request)) collection/views.py
  • 58. else: form = AlbumForm() return render_to_response('add.html', {'form' : form}, context_instance=RequestContext(request)) collection/views.py
  • 60. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 61. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 62. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 63. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 64. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 65. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 66. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 67. <form action="." method="post" enctype="multipart/form-data"> {% csrf_token %} {% for field in form %} <div class="fieldWrapper"> {{ field.errors }} {{ field.label_tag }}: {{ field }} </div> {% endfor %} <p><button type="submit">Adicionar</button></p> </form> templates/add.html
  • 69.
  • 70. /
  • 71. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), ) urls.py
  • 72. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), ) urls.py
  • 73. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), ) urls.py
  • 74. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), ) urls.py
  • 75. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 76. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 77. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 78. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 79. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 80. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 81. def index(request): albums = Album.objects.all().order_by('name') return render_to_response('index.html', {'albums' : albums}, context_instance=RequestContext(request)) collection/views.py
  • 82. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 83. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 84. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 85. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 86. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 87. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> </p> {% endfor %} templates/index.html
  • 88.
  • 90. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 91. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 92. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 93. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 94. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 95. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 96. from django.conf.urls.defaults import * from collection import views as collection_views urlpatterns = patterns('', url(r'^$', collection_views.index, name='album_index'), url(r'^add/$', collection_views.add), url(r'^delete/(?P<album_id>d+)/$', collection_views.delete, name='album_delete'), ) urls.py
  • 97. def delete(request, album_id): album = Album.objects.get(pk=album_id) album.delete() return redirect('album_index') collection/views.py
  • 98. def delete(request, album_id): album = Album.objects.get(pk=album_id) album.delete() return redirect('album_index') collection/views.py
  • 99. def delete(request, album_id): album = Album.objects.get(pk=album_id) album.delete() return redirect('album_index') collection/views.py
  • 100. def delete(request, album_id): album = Album.objects.get(pk=album_id) album.delete() return redirect('album_index') collection/views.py
  • 101. {% for album in albums %} <p> {% if album.cover %} <img src="{{album.cover}}" /> {% endif %} {{album.name}}<br /> {{album.artist}}<br /> <a href={% url album_delete album.pk %}>apagar</a> </p> {% endfor %} templates/index.html
  • 102.
  • 103.
  • 106. PYTHON

Editor's Notes

  1. Apresentar o básico do framework para que vocês conheçam melhor. Implementar uma aplicação para melhor entender o processo de desenvolvimento. Não adianta sair falando um monte de características e não mostrar nada muito real.
  2. Meu nome. Meu twitter. Maneira mais rápida de falar comigo.
  3. Email para contato.
  4. Vivemos num mundo tecnologico. Muita gente aqui usa a tecnologia com frequencia e muitos também trabalham com tecnologia. Posso dizer que a gente respira tecnologia.
  5. Isso tudo é tão normal pra gente, usar um computador, um celular, carro, geladeira, etc. Que se tornou algo quase natural. Pra que a tecnologia? A gente não faz essa pergunta com frequencia.
  6. É para isso? Um desenvolvedor pode achar o máximo uma aplicação ter um montão de funcionalidades. Um usuário vai achar isso um inferno, ele não consegue achar com facilidade o que deseja.
  7. Eu estava conversando com alguém de outra área. Ela afirmou não gostar muito de tecnologia e achar difícil. Depois de um certo tempo ela soltou uma frase: “a tecnologia não deveria facilitar a vida das pessoas?”. Exato! Deveria ser óbvio para gente, mas não é. Ninguém se questiona.
  8. Vocês sabem o que é isso? Um rádio. Sem botões. Seu manual poderia ter duas linhas. 1 – Para controlar o volume puxe a parte de cima do rádio verticalmente 2 – Para sintonizar gire. É isso. Muito simples. O nome desse produto é Hidden Radio.
  9. As pessoas querem tecnologia para usar, uma ferramenta que facilite sua vida. Um artista criando desenhos digitais.
  10. Uma professora usando um quadro eletronico, pois é mais fácil apresentar imagens ricar e interagir com elas.
  11. Essa máquina facilita infinitamente a colheita. Imaginem fazer tudo manualmente.
  12. E nós desenvolvedores? Nós criamos tecnologia. Mas nós usamos tecnologia para criar tecnologia. O que a gente usa não deveria ser dificil, deveria facilitar nossa vida.
  13. Quando eu conheci Python eu comecei a não gostar de várias outras linguagens. Eu sempre me questionava por que tinha que ser dificil daquele jeito. Python é um tipo de tecnologia que facilita muito a vida do programador. Hoje eu posso dizer que minha primeira tentativa para resolver algo com programação muito provavelmente será usando Python.
  14. Esse é um dos principios do Zen of Python que diz muito. Simples! Eu quero uma ferramenta pra botar minhas ideias em prática.
  15. Frameworks ajudam demais a colocar ideias em prática. É tudo uma questão de abstração. É código para ajudar a criar código. Você tem todo uma base que ajuda a criar uma aplicação mais facilmente.
  16. Essa frase de Isaac Newton tem muito a ver com computação. A gente está sempre sobre ombros de alguém. E isso é bom, assim podemos enxergar muito longe e criar coisas que não seriam viáveis se não fossem os ombros de gigantes. Frameworks funcionam como ombros.
  17. Django é um framework web escrito em Python. Vou falar bastante dele a partir de agora.
  18. Django foi criado para gerenciar um site jornalistico. Um dos principais requisitos era que fosse possível criar e fazer mudanças rápidas. Depois de um tempo o Django ele se tornou maduro o suficiente para ser usado por outras pessoas e foi liberado para o público. Hoje ele é o framework web mais popular pra Python E o nome? Alguem sabe de onde vem? Vem do músico de jazz Django Reinhardt
  19. O Django usa a conhecida arquitetura MVC Model – a representação dos dados View – como as coisas são exibidas Controller – pega a entrada do usuário, pega informações dos modelos, processa e devolve pra view
  20. Vou mostrar um pouco de código
  21. Vamos criar uma aplicação para gerenciar uma coleção musical Esse é o comando do django para iniciar um novo projeto.
  22. São criados esses arquivos manage.py – não deve ser modificado. Traz vários comandos para ajudar no desenvolvimento, por exemplo, syncdb, runserver, etc. settings.py – configurações do rpojeto urls.py – configuração das urls.
  23. Configurando o settings.
  24. Comando para criar uma nova aplicação Um projeto django é composto de várias aplicações.
  25. Cria uma pasta collection. Models.py – definição dos modelos da aplicação Tests.py – implementação dos testes Views.py – definição das views da aplicação.
  26. Como ficou o modelo album
  27. Adicionando app no settings
  28. Criando tabelas
  29. Primeira página: add/ para adicionar um novo album.
  30. Configurando o arquivo urls
  31. Settings.py
  32. Settings.py
  33. Settings.py
  34. Settings.py
  35. Precisamos de um formulário para adicionar algo num site. Vamos criar um.
  36. Form de acordo com o modelo.
  37. Define o modelo
  38. Exclui o campo cover, não quero adicionar a capa manualmente.
  39. View para adicionar um novo album
  40. Configurações no settings para definir onde ficarão os templates.
  41. Template add.
  42. Rodando o servidor
  43. resultado
  44. Proxima página, o index.
  45. Adicionando uma url
  46. View index
  47. Template index
  48. resultado
  49. Ultima url, deletar.
  50. Mais uma url.
  51. Settings.py
  52. Settings.py
  53. Settings.py
  54. Settings.py
  55. Settings.py
  56. Settings.py
  57. View delete
  58. resultado
  59. Resultado com css
  60. Vou colocar o código aqui.
  61. Vocês viram o basico. Django tem muita mais coisa. A internet tem muito material, vale a pena procurar.
  62. Sempre que necessário você pode usar todo o poder do Python. A função get_covers mostrou isso. Ali não tem nada especifico do Django.
  63. O Django é uma ótima ferramenta. Ele simplifica muita tarefa chata e agiliza muita coisa tambem.
  64. O Django é muito popular e sua comunidade é sempre ativa. Existem inúmeras aplicações criadas por terceiros prontas para serem usadas e vários desenvolvedores ajudando no projeto.
  65. Enfim, Django é uma ótima escolha.