Escolar Documentos
Profissional Documentos
Cultura Documentos
master
tutoriais / django-basic /
. .
Links
https://github.com/rg3915/tutoriais/tree/master/django-basic 1/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Ementa
Git
1 min de Python
O que é Django e pra que serve?
Entendendo o Padrão MVC
Ambiente Virtual de Desenvolvimento
Instalação
Qual será Nosso Projeto?
Configurando o Django
A view mais simples do mundo
Explorando o Admin
Introdução aos Templates
Entendendo o ORM do Django
CRUD com Functions Based Views
CRUD com Class Based Views
Várias formas de se fazer um formulário
Deploy no Heroku
Extra
Objetivo
Criar uma lista de filmes e retornar o filme de maior bilheteria.
Criar um formulário
Criar uma lista de filmes
Ver os detalhes de cada filme
https://github.com/rg3915/tutoriais/tree/master/django-basic 2/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Git
Crie uma conta no GitHub
Gere uma chave ssh na sua máquina
Configure sua ssh no settings do GitHub
Copiando a chave
cat ~/.ssh/id_rsa.pub
https://github.com/rg3915/tutoriais/tree/master/django-basic 3/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Criando o repositório
Edite o README.
## Instalação
* Clone o repositório.
* Crie um virtualenv com Python 3.
* Ative o virtualenv.
* Instale as dependências.
* Configure a instância com o .env.
* Execute as migrações no banco de dados.
* Execute os testes.
* Rode a aplicação.
https://github.com/rg3915/tutoriais/tree/master/django-basic 4/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
git status
git add README.md
git status
git commit -m "First Commit"
git push
1 min de Python
print("Python")
soma(25,9)
for i in range(10):
print(i)
movie = {
'name': 'Os Vingadores',
'category': 'ação',
'distributor': 'Disney',
'raised': 1.519,
'release': '2012-04-27',
}
movie['name']
movie['category']
movie['release']
import datetime
class Movie(object):
https://github.com/rg3915/tutoriais/tree/master/django-basic 5/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
self.distributor = distributor
self.release = release
def count_string_movie(self):
return len(self.name)
if __name__ == '__main__':
movie = Movie()
movie.name = 'Titanic'
movie.category = 'aventura'
movie.distributor = 'Paramount'
movie.release = datetime.date(1998, 1, 16)
print(movie)
print(movie.name)
print(movie.category)
print(movie.distributor)
print(movie.release)
print(movie.count_string_movie())
https://github.com/rg3915/tutoriais/tree/master/django-basic 6/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
https://www.djangosites.org/
MVC x MTV
Model - é o modelo, a camada de abstração do banco de dados, onde acontece o
ORM
View - é o controlador, onde acontece as regras de negócio e a comunicação entre a
base de dados e o navegador
Templates - é a camada de apresentação, são as páginas html
https://github.com/rg3915/tutoriais/tree/master/django-basic 7/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
https://github.com/rg3915/tutoriais/tree/master/django-basic 8/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Ativando o virtualenv
source .venv/bin/activate
# .venv/Scripts/activate.bat # Windows
https://github.com/rg3915/tutoriais/tree/master/django-basic 9/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Obs: todos os pacotes instalados com o ambiente ativado serão instalados dentro do
ambiente e visíveis somente nele.
$ sa
(.venv):/djangotutorial$
(.venv):/djangotutorial$ deactivate
Instalação
Python 3
Pip
Virtualenv
https://github.com/rg3915/tutoriais/tree/master/django-basic 10/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Ambiente: .venv
Projeto: myproject
App: core
Instalando o Django
pip freeze
Django==1.11
https://github.com/rg3915/tutoriais/tree/master/django-basic 11/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
repare no ponto final do comando, isto permite que o arquivo manage.py fique na pasta
"principal", pasta .venv .
Criando a app
cd myproject
python ../manage.py startapp core
cd ..
.
|-- manage.py
|-- myproject
| |-- core
| | |-- admin.py
| | |-- apps.py
| | |-- __init__.py
| | |-- models.py
| | |-- tests.py
| | `-- views.py
| |-- __init__.py
| |-- settings.py
| |-- urls.py
| `-- wsgi.py
https://github.com/rg3915/tutoriais/tree/master/django-basic 12/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
INSTALLED_APPS = [
# ...
'myproject.core',
]
manage migrate
Rodando a aplicação
manage runserver
# ou
# manage runserver 8080
http://localhost:8000/
https://github.com/rg3915/tutoriais/tree/master/django-basic 13/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Configurando o Django
touch .env
SECRET_KEY=su4_s3cr3t_k3y_sup3r_s3cr3t4
Note que eu tirei as aspas simples e o espaço em branco entre o sinal de igual.
SECRET_KEY = config('SECRET_KEY')
SECRET_KEY=su4_s3cr3t_k3y_sup3r_s3cr3t4
DEBUG=True
ALLOWED_HOSTS=127.0.0.1, .localhost
E o settings.py
https://github.com/rg3915/tutoriais/tree/master/django-basic 14/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
README.md
SECRET_KEY = config('SECRET_KEY')
.gitignore
Antes de "commitar" nosso código digite git status .
Repare que a pasta .venv e o db.sqlite3 serão versionados, mas não deve.
Boas práticas: NÃO versione seu ambiente virtual e nem seu banco de dados.
.venv
*.sqlite3
git add .
git commit -m "First project"
git push
.
|--
|-- myproject
https://github.com/rg3915/tutoriais/tree/master/django-basic 15/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
| |-- core
| | |-- ...
| | `-- views.py
| |-- settings.py
| |-- urls.py
Editando views.py
def home(request):
return HttpResponse('<h1>Django</h1><h3>Bem-vindo ao Django!</h3>')
Editando urls.py
urlpatterns = [
url(r'^$', home),
url(r'^admin/', admin.site.urls),
]
Explorando o Admin
https://github.com/rg3915/tutoriais/tree/master/django-basic 16/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Editando o settings.py
LANGUAGE_CODE = 'pt-br'
TIME_ZONE = 'America/Sao_Paulo'
LOGIN_URL = '/admin/login'
https://github.com/rg3915/tutoriais/tree/master/django-basic 17/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Testes
class HomeTest(TestCase):
def setUp(self):
self.resp = self.client.get('/')
def test_get(self):
''' get / deve retornar status code 200. '''
self.assertEqual(200, self.resp.status_code)
def test_template(self):
''' Home deve usar template index.html '''
self.assertTemplateUsed(self.resp, 'index.html')
Leia: "pytest: escreva menos, teste mais" - Erick Wilder de Oliveira - https://goo.gl/8E9FB1
Editando views.py
# def home(request):
# return HttpResponse('<h1>Django</h1><h3>Bem-vindo ao Django!</h3>')
def home(request):
return render(request, 'index.html')
Criando o index.html
Estando na pasta venv digite
https://github.com/rg3915/tutoriais/tree/master/django-basic 18/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
cd myproject
mkdir -p core/templates
echo "<html><body><h1>Tutorial Django</h1><h3>Bem-vindo ao Django.</h3></body>
Explorando o layoutit
Editando models.py
Básico: Filmes
class Distributor(models.Model):
distributor = models.CharField('distribuidor', max_length=50, unique=True)
class Meta:
''' É uma classe Builtin do Django com recursos adicionais '''
ordering = ['distributor']
verbose_name = 'distribuidor'
verbose_name_plural = 'distribuidores'
def __str__(self):
''' Retorna o distributor ao invés de 'Distributor.object' '''
return self.distributor
class Category(models.Model):
category = models.CharField('categoria', max_length=50, unique=True)
https://github.com/rg3915/tutoriais/tree/master/django-basic 19/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
class Meta:
ordering = ['category']
verbose_name = 'categoria'
verbose_name_plural = 'categorias'
def __str__(self):
return self.category
class Movie(models.Model):
movie = models.CharField('filme', max_length=100)
category = models.ForeignKey(
'Category', verbose_name='categoria', related_name='movie_category')
distributor = models.ForeignKey(
'Distributor', verbose_name='distribuidor', related_name='movie_distri
raised = models.DecimalField('arrecadou', max_digits=4, decimal_places=3)
liked = models.BooleanField('gostou', default=True)
release = models.DateTimeField(u'lançamento')
class Meta:
''' O sinal de menos ordena a data de forma decrescente, ou seja,
mais recente primeiro. '''
ordering = ['-release']
verbose_name = 'filme'
verbose_name_plural = 'filmes'
def __str__(self):
return self.movie
def get_absolute_url(self):
return r('core:movie_detail', kwargs={'pk': self.pk})
Note que get_absolute_url usa reverse_lazy , que no caso foi renomeado através de
um alias para r .
Tipos de campos
https://docs.djangoproject.com/en/1.10/ref/models/fields/
Atualizando o banco
https://github.com/rg3915/tutoriais/tree/master/django-basic 20/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
https://docs.djangoproject.com/en/1.10/ref/models/querysets/
https://pt.wikipedia.org/wiki/Lista_de_filmes_de_maior_bilheteria
Admin novamente
admin.site.register(Distributor)
admin.site.register(Category)
admin.site.register(Movie)
https://github.com/rg3915/tutoriais/tree/master/django-basic 21/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Em settings.py
INSTALLED_APPS = [
# ...
# thirty apps
'django_extensions',
# ...
]
manage shell_plus
mkdir shell
touch shell/{categorys.py,distributors.py,movies.py}
Atenção: caso você já tenha instalado o shell_plus provavelmente vai dar um erro ao
rodar os scripts acima, então tente com
Leia mais
https://github.com/rg3915/tutoriais/tree/master/django-basic 22/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
category = Category.objects.get(category='aventura')
distributor = Distributor.objects.get(distributor='Lionsgate')
Movie.objects.create(
movie='Jogos Vorazes',
category=category,
distributor=distributor,
raised=2.308,
release=datetime.date(2012, 3, 23)
)
for i in q.values():
print(i)
# Experimente
for i in q:
i.movie, i.category, i.raised
# Exemplos de filtro
https://github.com/rg3915/tutoriais/tree/master/django-basic 23/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
# Exemplo de update
Movie.objects.filter(movie__icontains='Exterminador').update(
movie='O Exterminador do Futuro: Gênesis', release=datetime.date(2015, 7,
# Exemplo de delete
Movie.objects.filter(id=1).delete()
# Customer.objects.all().delete() # perigoso
t = Movie.objects.get(movie='Titanic')
t
t.id
Movie.objects.filter(id=t.id).delete()
Movie.objects.filter(movie='Titanic')
Movie.objects.filter(movie='Titanic').count()
Movie.objects.filter(release__year=2012).count()
# Movie.objects.filter(release__year__gte=2000).count() # filmes > 2000
Views.py
def movie_list(request):
movies = Movie.objects.all()
context = {'movies': movies}
return render(request, 'core/movie_list.html', context)
urls.py
touch core/urls.py
Editando core/urls.py
https://github.com/rg3915/tutoriais/tree/master/django-basic 24/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
urlpatterns = [
url(r'^$', home, name='home'),
url(r'^movie/$', movie_list, name='movie_list'),
]
Refatorando urls.py
urlpatterns = [
url(r'', include('myproject.core.urls', namespace='core')),
url(r'^admin/', admin.site.urls),
]
Criando os templates
mkdir core/templates/core
touch core/templates/{base,menu}.html
touch core/templates/core/{movie_list,movie_detail,movie_form}.html
Temos
core
├── admin.py
├── models.py
├── templates
│ ├── base.html
│ ├── index.html
│ ├── menu.html
│ └── core
│ ├── movie_detail.html
│ ├── movie_form.html
│ └── movie_list.html
├── tests.py
└── views.py
Variáveis
Acessando objetos
https://github.com/rg3915/tutoriais/tree/master/django-basic 25/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
{{ objeto }}
Acessando atributos
{{ objeto.atributo }}
Tags
{% tags %}
Exemplo:
{% if condicao %}
<!-- algum comando -->
{% endif %}
Vamos editar:
menu.html
https://github.com/rg3915/tutoriais/tree/master/django-basic 26/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
</div>
</div>
base.html
{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="shortcut icon" href="https://www.djangoproject.com/favicon.ico"
{% block title %}
<title>Filmes</title>
{% endblock title %}
<style type="text/css">
/* Move down content because we have a fixed navbar that is 50px tall */
body {
padding-top: 60px;
padding-bottom: 40px;
/*color: #5a5a5a;*/
}
</style>
</head>
<body>
{% include "menu.html" %}
Herança de templates
index.html
{% extends "base.html" %}
https://github.com/rg3915/tutoriais/tree/master/django-basic 27/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
{% block content %}
<div class="container">
<div class="jumbotron">
<h1>Tutorial Django</h1>
<h3>Bem-vindo ao Django!</h3>
</div>
</div>
{% endblock content %}
movie_list.html
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="page-header">
<a class="btn btn-primary pull-right" href="{% url 'core:movie_add' %}">
<h2><a href="?great_movie=1">Filme de maior bilheteria</a></h2>
</div>
{% if movies %}
<table class="table table-striped">
<thead>
<tr>
<th>Filme</th>
<th>Categoria</th>
<th>Distribuidor</th>
<th>Bilheteria (bilhões)</th>
<th>Lançamento</th>
<th>Gostou</th>
</tr>
</thead>
<tbody>
{% for movie in movies %}
<tr>
<td><a href="{{ movie.get_absolute_url }}">{{ movie.movie }}</a></
<td>{{ movie.category }}</td>
<td>{{ movie.distributor }}</td>
<td>U$ {{ movie.raised }}</td>
<td>{{ movie.release|date:"d/m/Y" }}</td>
{% if movie.liked %}
<td><span class="glyphicon glyphicon-ok-sign" style="color: #44A
{% else %}
<td><span class="glyphicon glyphicon-minus-sign" style="color: #
{% endif %}
</tr>
{% endfor %}
</tbody>
</table>
https://github.com/rg3915/tutoriais/tree/master/django-basic 28/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
{% else %}
<p class="alert alert-warning">Sem itens na lista.</p>
{% endif %}
</div>
{% endblock content %}
Atenção: provavelmente vai dar erro em href="{% url 'core:movie_add' %}" porque a
url não existe ainda. Deixe href vazio temporariamente.
Visualizando os detalhes
urls.py
https://github.com/rg3915/tutoriais/tree/master/django-basic 29/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
movie_detail.html
{% extends "base.html" %}
{% block content %}
<div class="container">
<div class="row">
<ul class="breadcrumb">
<li><a href="{% url 'core:movie_list' %}">Filmes</a> <span class="divi
<li class="active">{{ movie.movie }}</li>
</ul>
https://github.com/rg3915/tutoriais/tree/master/django-basic 30/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
http://getbootstrap.com/
http://getbootstrap.com/examples/theme/
http://www.layoutit.com/
https://ccbv.co.uk/
Leia: "Django Class Based Views - o que são e por que usar" - Caio Carrara
https://goo.gl/xnfqx1
https://speakerdeck.com/cacarrara/django-class-based-views
https://github.com/rg3915/tutoriais/tree/master/django-basic 31/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
class MovieList(ListView):
template_name = 'core/movie_list.html'
model = Movie
context_object_name = 'movies'
def get_queryset(self):
m = Movie.objects.all()
# Filme de maior bilheteria
if self.request.GET.get('great_movie', False):
q = Movie.objects.all().aggregate(Max('raised'))
m = Movie.objects.filter(raised=q['raised__max'])
return m
class MovieDetail(DetailView):
template_name = 'core/movie_detail.html'
model = Movie
Formulários
class MovieCreate(CreateView):
template_name = 'core/movie_form.html'
model = Movie
fields = '__all__'
success_url = r('core:movie_list')
Refatorando o urls.py
urlpatterns = [
url(r'^$', c.home, name='home'),
url(r'^movie/$', c.MovieList.as_view(), name='movie_list'),
url(r'^movie/(?P<pk>\d+)/$', c.MovieDetail.as_view(), name='movie_detail')
url(r'^movie/add/$', c.MovieCreate.as_view(), name='movie_add'),
]
Editando movie_form.html
https://github.com/rg3915/tutoriais/tree/master/django-basic 32/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
{% extends "base.html" %}
{% block content %}
<div class="container">
<form class="form-horizontal" action="." method="POST">
<legend>Cadastrar</legend>
{% csrf_token %}
{{ form.as_p }}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" id="id_submit" class="btn btn-primary">Salvar<
</div>
</div>
</form>
</div>
{% endblock content %}
{% extends "base.html" %}
{% block content %}
https://github.com/rg3915/tutoriais/tree/master/django-basic 33/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
<div class="container">
<form class="form-horizontal" action="." method="POST">
<legend>Cadastrar</legend>
{% csrf_token %}
<div class="form-group">
<label for="id_movie">Filme</label>
<input type="text" id="id_movie" name="movie" class="form-control">
</div>
<div class="form-group">
<label for="id_category">Categoria</label>
<input type="text" id="id_category" name="category" class="form-control"
</div>
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" id="id_submit" class="btn btn-primary">Salvar</b
</div>
</div>
</form>
</div>
{% endblock content %}
{{ form }}
{{ form.as_p }}
{{ form.as_ul }}
{{ form.as_table }}
Nosso formulário
{% extends "base.html" %}
{% block content %}
<form action="" method="POST">
{% csrf_token %}
{{ form.as_p }}
</form>
{% endblock content %}
https://github.com/rg3915/tutoriais/tree/master/django-basic 34/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Antes digite
INSTALLED_APPS = [
# ...
# thirty apps
# ...
'bootstrapform',
# my apps
'myproject.core',
]
Editando o formulário
{% extends "base.html" %}
{% load bootstrap %}
{% block content %}
<div class="container">
<form class="form-horizontal" action="." method="POST">
<legend>Cadastrar</legend>
{% csrf_token %}
{{ form.movie|bootstrap_horizontal }}
{{ form.category|bootstrap_horizontal }}
{{ form.distributor|bootstrap_horizontal }}
{{ form.raised|bootstrap_horizontal }}
https://github.com/rg3915/tutoriais/tree/master/django-basic 35/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
{{ form.liked|bootstrap_horizontal }}
{{ form.release|bootstrap_horizontal }}
<div class="form-group">
<div class="col-sm-10 col-sm-offset-2">
<button type="submit" id="id_submit" class="btn btn-
primary">Salvar</button>
</div>
</div>
</form>
</div>
{% endblock content %}
Deploy no Heroku
Criar conta no Heroku
Instalar Heroku Toolbelt
no terminal digite heroku
heroku login
heroku --version
Nós temos um projeto, mas podemos ter várias instâncias. Então precisamos separar os
elementos da instância.
https://github.com/rg3915/tutoriais/tree/master/django-basic 36/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Configurar wsgi.py
...
application = Cling(get_wsgi_application())
Inserir em requirements.txt
gunicorn==19.7.1
psycopg2==2.7.1
E runtime.txt
git status
git add .
git commit -m "Configurações para Heroku"
git push
https://github.com/rg3915/tutoriais/tree/master/django-basic 37/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
git remote -v
heroku config
heroku config:push
heroku config
git push heroku master --force
heroku open
https://github.com/xavdid/heroku-config
heroku config
heroku open
Nota: provavelmente você vai precisar fazer a migração do banco dentro do Heroku. Para
isso digite:
https://github.com/rg3915/tutoriais/tree/master/django-basic 38/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Livros
Two Scoops of Django 1.8 de Daniel and Audrey Roy Greenfeld (@pydanny and @audreyr)
Cursos
Final
Extra
Refatorando o Admin.py
@admin.register(Movie)
class MovieAdmin(admin.ModelAdmin):
search_fields = ('movie', 'distributor__distributor')
list_display = ('movie', 'distributor')
admin.site.register(Distributor)
admin.site.register(Category)
https://github.com/rg3915/tutoriais/tree/master/django-basic 39/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
https://docs.djangoproject.com/en/1.10/ref/contrib/admin/#modeladmin-options
Arquivos estáticos
Vamos criar algumas pastas
mkdir -p core/static/{css,img,js}
touch core/static/css/main.css
body {
padding-top: 60px;
padding-bottom: 40px;
}
https://github.com/rg3915/tutoriais/tree/master/django-basic 40/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais
Em main.css acrescente
#image {
width: 200px;
}
E em index.html acrescente
<div class="pull-right">
<img id="image" src="{% static 'img/XebTa9B.png' %}" alt="">
</div>
{% extends "base.html" %}
{% load static %}
{% block content %}
<div class="container">
<div class="jumbotron">
<div class="pull-right">
<img id="image" src="{% static 'img/XebTa9B.png' %}" alt="">
</div>
<h1>Tutorial Django</h1>
<h3>Bem-vindo ao Django!</h3>
</div>
</div>
{% endblock content %}
Links
Participem do Grupy-SP
Give feedback
https://github.com/rg3915/tutoriais/tree/master/django-basic 41/41