Você está na página 1de 41

12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

rg3915 / tutoriais Public

Code Issues Pull requests Actions Projects Security Insights

master

tutoriais / django-basic /

grandeportal … on May 16, 2017

. .

img 6 years ago

myproject 6 years ago

shell 6 years ago

Makefile 6 years ago

Procfile 6 years ago

README.md 6 years ago

links.md 6 years ago

manage.py 6 years ago

requirements.txt 6 years ago

runtime.txt 6 years ago

Mini Curso de Django Básico


Entrar aqui: https://rg3915.github.io/tutoriais/

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

Generating a new SSH key

ssh-keygen -t rsa -b 4096 -C "email@example.com"

Generating public/private rsa key pair.


Enter file in which to save the key (/home/vagrant/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/vagrant/.ssh/id_rsa.
Your public key has been saved in /home/vagrant/.ssh/id_rsa.pub.
The key fingerprint is:
28:67:2f:04:39:ff:04:6c:d4:e4:5d:68:04:05:eb:ea email@example.com
The key's randomart image is:
+--[ RSA 4096]----+
| .o+=o.. |
| + ..oo. |
| + + o.. |
| = + |
| . * S |
| = = |
| o o |
| . . |
| E |
+-----------------+

Adicionando seu SSH Key no ssh-agent

eval "$(ssh-agent -s)"


ssh-add ~/.ssh/id_rsa

Copiando a chave

cat ~/.ssh/id_rsa.pub

Configurando o SSH no GitHub

Clique no seu perfil e vá em Settings.

https://github.com/rg3915/tutoriais/tree/master/django-basic 3/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Em seguida vá em SSH and GPG keys.

Clique no botão New SSH key e cole o id_rsa.pub .

Criando o repositório

Agora crie um novo repositório clicando no icone '+' e em new repository.

Vamos chamar o repositório de djangotutorial.

Agora clone o projeto digitando

git clone git@github.com:seunome/djangotutorial.git


cd djangotutorial

Para fazer o clone via HTTPS digite

git clone https://github.com/seunome/djangotutorial.git

Talvez você precise configurar no seu terminal os seguintes comandos

git config --global user.name "Seu Nome"


git config --global user.email "seuemail@example.com"

Edite o README.

# Mini Curso de Django Básico

## 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.

git clone https://github.com/seunome/djangotutorial.git


cd djangotutorial
python3 -m venv .venv
source .venv/bin/activate
# .venv\Scripts\activate.bat # Windows
python -m pip install -r requirements.txt
python contrib/env_gen.py
python manage.py migrate

https://github.com/rg3915/tutoriais/tree/master/django-basic 4/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

python manage.py test


python manage.py runserver

E vamos subir as alterações para o GitHub.

git status
git add README.md
git status
git commit -m "First Commit"
git push

1 min de Python

print("Python")

def soma(a, b):


return a + b

soma(25,9)

lista = ['a', 10, 5.5]


for i in lista:
print(i)

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):

def __init__(self, name='', category='', distributor='', release=''):


self.name = name
self.category = category

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())

O que é Django e pra que serve?

Segundo Django Brasil,

Django é um framework web de alto nível escrito em Python que estimula o


desenvolvimento rápido e limpo.

adota o padrão MTV


possui ORM
admin
herança de templates e modelos
open source

https://github.com/rg3915/tutoriais/tree/master/django-basic 6/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Quem usa Django?

https://www.djangosites.org/

Entendendo o Padrão MVC

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

Veja o processo de um request e response.

https://github.com/rg3915/tutoriais/tree/master/django-basic 8/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Ambiente Virtual de Desenvolvimento

O Python 3 já tem um virtualenv como bateria inclusa. virtualenv é um ambiente onde


você isola as dependências do seu projeto.

python3 -m venv .venv

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.

Dica: No Linux, edite o arquivo ~/.bashrc .

alias sa='source .venv/bin/activate;'

Assim você cria atalhos para ativar seus ambientes:

$ sa

Dica: Para diminuir o caminho do prompt digite

$ PS1="(`basename \"$VIRTUAL_ENV\"`):/\W$ "

O caminho vai ficar assim

(.venv):/djangotutorial$

Onde (.venv) é o nome do ambiente e :/djangotutorial$ é a pasta atual.

Para desativar o ambiente digitamos

(.venv):/djangotutorial$ deactivate

Instalação

Python 3
Pip
Virtualenv

Instalando Python 3 no Windows

Vá em www.python.org/downloads/ e baixe Python 3.6. Ao instalar não esqueça de marcar


o check 'Add Python 3.6 to PATH'.

https://github.com/rg3915/tutoriais/tree/master/django-basic 10/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Instalando Python 3 no Linux ou Mac

Sugiro este tutorial de instalação com pyenv https://github.com/rg3915/django-


experience/wiki/Instalando-o-pyenv

Qual será Nosso Projeto?

Ambiente: .venv
Projeto: myproject
App: core

Instalando o Django

pip install django

Vendo o que foi instalado

pip freeze
Django==1.11

Crie o requirements.txt (os ingredientes do bolo)

pip freeze > requirements.txt

https://github.com/rg3915/tutoriais/tree/master/django-basic 11/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Criando o projeto e a App


Para criar o projeto digite

django-admin.py startproject myproject .

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 ..

Dica: você pode digitar

manage startapp core

mas para funcionar este comando você deve editar o ~/.bashrc .

alias manage='python $VIRTUAL_ENV/../manage.py'

O que temos até aqui?

.
|-- 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

Django funcionando em nível 0

Declarando o app core em settings.py

INSTALLED_APPS = [
# ...
'myproject.core',
]

Criando a primeira migração

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

Importante: nunca coloque sua SECRET_KEY no git.

Vamos editar o settings.py .

Extraia a SECRET_KEY , crie um arquivo .env na pasta principal e coloque-o lá.

touch .env

O .env vai ficar assim:

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.

E o settings.py vai ficar assim:

from decouple import config, Csv

SECRET_KEY = config('SECRET_KEY')

Repare que estamos usando o python-decouple. Para instala-lo digite

pip install python-decouple

Voltando ao .env façamos

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')

DEBUG = config('DEBUG', default=False, cast=bool)

ALLOWED_HOSTS = config('ALLOWED_HOSTS', default=[], cast=Csv())

Configurando melhor o banco de dados

from dj_database_url import parse as dburl

default_dburl = 'sqlite:///' + os.path.join(BASE_DIR, 'db.sqlite3')


DATABASES = {
'default': config('DATABASE_URL', default=default_dburl, cast=dburl),
}

Note que estamos usando o dj-database-url.

pip install dj-database-url

.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.

Vamos editar o .gitignore .

.venv
*.sqlite3

Pronto! Agora você pode dar seu primeito commit .

git add .
git commit -m "First project"
git push

A view mais simples do mundo

.
|--
|-- 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

# from django.shortcuts import render


from django.http import HttpResponse

def home(request):
return HttpResponse('<h1>Django</h1><h3>Bem-vindo ao Django!</h3>')

Editando urls.py

from django.conf.urls import url


from django.contrib import admin
from myproject.core.views import home

urlpatterns = [
url(r'^$', home),
url(r'^admin/', admin.site.urls),
]

Explorando o Admin

manage createsuperuser --username='admin' --email=''

https://github.com/rg3915/tutoriais/tree/master/django-basic 16/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Introdução aos Templates

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

Teste: Verificar se existe a página index.html.

from django.test import TestCase

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

from django.shortcuts import render


# from django.http import HttpResponse

# 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

from django.db import models


from django.core.urlresolvers import reverse_lazy as r

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 .

Note também que 'core:movie_detail' é o namespace e name da url respectivamente.

Nota: caso dê algum erro, comente esta função temporariamente.

Tipos de campos
https://docs.djangoproject.com/en/1.10/ref/models/fields/

Atualizando o banco

python manage.py makemigrations


python manage.py migrate

https://github.com/rg3915/tutoriais/tree/master/django-basic 20/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Entendendo o ORM do Django

Explorando um pouco as queryset.

$ python manage.py shell


Python 3.5.0 (default, Dec 8 2015, 01:17:16)
[GCC 4.8.4] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>>

Precisamos importar o models.

>>> from myproject.core.models import Distributor, Category, Movie


>>> import datetime
>>> Distributor.objects.create(distributor='Disney')
>>> Category.objects.create(category='ação')
>>> category = Category.objects.get(category='ação')
distributor = Distributor.objects.get(distributor__icontains='disney')
Movie.objects.create(
movie='Os Vingadores',
category=category,
distributor=distributor,
raised=1.519,
release=datetime.date(2012, 4, 27)
)
>>> m = Movie.objects.all()
>>> m
>>> print(m.query)

https://docs.djangoproject.com/en/1.10/ref/models/querysets/

https://pt.wikipedia.org/wiki/Lista_de_filmes_de_maior_bilheteria

Admin novamente

from django.contrib import admin


from .models import Distributor, Category, Movie

admin.site.register(Distributor)
admin.site.register(Category)
admin.site.register(Movie)

Turbinando o shell com iPython e django extensions

https://github.com/rg3915/tutoriais/tree/master/django-basic 21/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

pip install ipython


pip install django-extensions

Em settings.py

INSTALLED_APPS = [
# ...
# thirty apps
'django_extensions',
# ...
]

Agora podemos digitar

manage shell_plus

Explorando mais o shell do Django


Façamos

mkdir shell
touch shell/{categorys.py,distributors.py,movies.py}

Veja o código de cada arquivo em shell/.

Para rodar o script façamos

manage shell < shell/categorys.py


manage shell < shell/distributors.py
manage shell < shell/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

python manage.py shell_plus < shell/categorys.py


python manage.py shell_plus < shell/distributors.py
python manage.py shell_plus < shell/movies.py

Leia mais

from myproject.core.models import Distributor, Category, Movie


import datetime

https://github.com/rg3915/tutoriais/tree/master/django-basic 22/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

# Podemos criar uma instância do objeto e depois salvar.


obj = Distributor(distributor='Paramount Pictures')
obj.save()

# Veja um exemplo de como criar um Distributor diretamente.


Distributor.objects.create(distributor='Universal Pictures')
Distributor.objects.create(distributor='Walt Disney Pictures')

CATEGORY_LIST = ['ação', 'animação', 'aventura', 'comedia', 'guerra', 'suspens


# Usando um List Comprehension podemos definir todos os objetos a serem
# inseridos no Django
obj = [Category(category=val) for val in CATEGORY_LIST]
# O comando bulk_create é muito rápido!
Category.objects.bulk_create(obj)

# O comando get "pega" um objeto


category = Category.objects.get(category='ação')
distributor = Distributor.objects.get(distributor__istartswith='Warner')
Movie.objects.create(
movie='O Exterminador do Futuro',
category=category, # para ser usado aqui
distributor=distributor,
raised=1.756,
release=datetime.date(1984, 10, 26)
)

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)
)

q = Movie.objects.all() # listando todos os filmes


q.count()
q
q.values() # dicionario
q.values_list() # lista

for i in q.values():
print(i)

# Experimente
for i in q:
i.movie, i.category, i.raised

dir(q) # veja todas as opções do objeto.

# 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

Movie.objects.filter(category='ação') # retorna erro


Movie.objects.filter(category__category='ação')
Movie.objects.filter(distributor__distributor__icontains='gate')

# 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

# Filme de maior bilheteria


from django.db.models import Max
q = Movie.objects.all().aggregate(Max('raised'))
q
Movie.objects.filter(raised=q['raised__max'])

CRUD com Functions Based Views

Views.py

from django.shortcuts import render


from .models import Movie

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

from django.conf.urls import url


from .views import home, movie_list

urlpatterns = [
url(r'^$', home, name='home'),
url(r'^movie/$', movie_list, name='movie_list'),
]

Refatorando urls.py

from django.conf.urls import include, url


from django.contrib import admin

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 %}

{% for item in objeto %}


{{ item.atributo }}
{% endfor %}

Vamos editar:

menu.html

<!-- Menu -->


<div class="navbar navbar-inverse navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="current"><a href="{% url 'core:home' %}"><span class="glyph
<li><a href="{% url 'core:movie_list' %}"><span class="glyphicon glyph
</ul>
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'admin:index' %}">Admin</a></li>
</ul>
</div>

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 %}

<!-- Bootstrap core CSS -->


<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3
<script src="https://code.jquery.com/jquery-2.2.4.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.

<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" %}

{% block content %}{% endblock content %}


</body>
</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.

Talvez dê erro em href="{{ movie.get_absolute_url }}" também.

Visualizando os detalhes

from django.shortcuts import render, get_object_or_404

def movie_detail(request, pk):


movie = get_object_or_404(Movie, pk=pk)
context = {'movie': movie}
return render(request, 'core/movie_detail.html', context)

urls.py

from .views import movie_detail

url(r'^movie/(?P<pk>\d+)/$', movie_detail, name='movie_detail'),

Agora você pode voltar com href="{{ movie.get_absolute_url }}" .

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>

<div class="col-sm-6 col-md-4">


<div class="list-group">
<h1>
{{ movie.movie}}
{% if movie.liked %}
<td><span class="pull-right glyphicon glyphicon-ok-sign" style="
{% else %}
<td><span class="pull-right glyphicon glyphicon-minus-sign" styl
{% endif %}
</h1>
<div class="list-group-item">
<h4>{{ movie.category }}</h4>
</div>
<div class="list-group-item">
<h4>{{ movie.distributor }}</h4>
</div>
<div class="list-group-item">
<h3>U$ {{ movie.raised }}</h3>
</div>
<div class="list-group-item">
<h4>{{ movie.release|date:"d/m/Y" }}</h4>
</div>
</div>
</div>
</div>
</div>
{% endblock content %}

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/

CRUD com Class Based Views


https://docs.djangoproject.com/en/1.10/topics/class-based-views/

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

Editando o views.py para lista

from django.views.generic import CreateView, ListView, DetailView


from django.db.models import Max

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

Editando o views.py para formulário

from django.core.urlresolvers import reverse_lazy as r

class MovieCreate(CreateView):
template_name = 'core/movie_form.html'
model = Movie
fields = '__all__'
success_url = r('core:movie_list')

Refatorando o urls.py

from django.conf.urls import url


from myproject.core import views as c

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 %}

Várias formas de se fazer um formulário

Existem várias formas de se criar um formulário, qual deles eu uso?

1 - Fazendo tudo na mão com html puro

{% 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 %}

2 - Usando as tags do Django

{{ 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

3 - Usando {{ field.label }} e {{ field }}

{% for field in form %}


<div class="form-group">
<div class="control-label col-sm-2">
{{ field.errors }}
{{ field.label }}
</div>
<div class="col-sm-2">
{{ field }}
</div>
</div>
{% endfor %}

4 - Usando bibliotecas como o django-bootstrap-form

Antes digite

pip install django-bootstrap-form

E em settings.py , em INSTALLED_APPS insira 'bootstrapform', .

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.

pip install python-decouple

Lê as configurações da instância a partir das variáveis de ambiente do sistema a partir do


arquivo .env .

https://github.com/rg3915/tutoriais/tree/master/django-basic 36/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

pip install dj-database-url

Configurar os arquivos estáticos, em settins.py digite

STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')

O dj-static que servirá os arquivos, pois o Django não faz isso.

Configurar wsgi.py

from dj_static import Cling

...

application = Cling(get_wsgi_application())

pip freeze > requirements.txt

Inserir em requirements.txt

gunicorn==19.7.1
psycopg2==2.7.1

O gunicorn é o servidor de aplicação.

E o psycopg2 é o drive do Postgres para o Python.

Crie o arquivo Procfile

echo "web: gunicorn myproject.wsgi --log-file -" > Procfile

E runtime.txt

echo python-3.6.1 > runtime.txt

Suba as alterações para o GitHub

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

Crie uma app no Heroku

heroku apps:create djangotutorial-regis

Veja o novo repositório

git remote -v

Talvez você precise do comando

heroku git:remote -a djangotutorial-regis

Primeiro enviamos as configurações para o Heroku

heroku config
heroku config:push
heroku config
git push heroku master --force
heroku open

https://github.com/xavdid/heroku-config

heroku plugins:install heroku-config

Se não der certo use a configuração manual

heroku config:set SECRET_KEY=su4_s3cr3t_k3y_sup3r_s3cr3t4


heroku config:set DEBUG=False
heroku config:set ALLOWED_HOSTS="127.0.0.1, .localhost, .herokuapp.com"

heroku config
heroku open

Nota: provavelmente você vai precisar fazer a migração do banco dentro do Heroku. Para
isso digite:

heroku run python manage.py migrate


heroku run python manage.py createsuperuser

https://github.com/rg3915/tutoriais/tree/master/django-basic 38/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

Livros

Django Essencial de Julia Elman da Novatec

Two Scoops of Django 1.8 de Daniel and Audrey Roy Greenfeld (@pydanny and @audreyr)

The Django Book

Cursos

Welcome to the Django by @henriquebastos

Construa um E-Commerce com Python 3 e Django by @GilenoFilho

Python para Zumbis

CodingEntrepreneurs Try Django 1.9

Final

# Filme de maior bilheteria


from django.db.models import Max
q = Movie.objects.all().aggregate(Max('raised'))
q
m = Movie.objects.filter(raised=q['raised__max'])
m.values()
m[0].movie, m[0].raised

Extra

Refatorando o Admin.py

from django.contrib import admin


from myproject.core.models import Distributor, Category, Movie

@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}

Em css vamos criar um main.css

touch core/static/css/main.css

Seu conteúdo será

body {
padding-top: 60px;
padding-bottom: 40px;
}

Baixe uma imagem bem bonita e coloque em img . Eu escolhi essa:

Agora vamos refatorar base.html . Troque <style>...</style> por

https://github.com/rg3915/tutoriais/tree/master/django-basic 40/41
12/03/2023, 11:08 tutoriais/django-basic at master · rg3915/tutoriais

<link rel="stylesheet" href="{% static 'css/main.css' %}">

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>

O index.html vai ficar assim:

{% 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

Meu portfólio http://rg3915.github.io/

Give feedback

https://github.com/rg3915/tutoriais/tree/master/django-basic 41/41

Você também pode gostar