Curso de introdução ao desenvolvimento Web com Python e Django grátis!

Olá,

Recentemente gravei algumas aulas para auxiliar quem está começando a desenvolver para a Web utilizando Python e Django.

É um curso introdutório que não apresenta todo o processo de desenvolvimento, mas ensina como as coisas funcionam no Django para que você possa começar a aprender.

Python e Django

Todos os vídeos estão em uma playlist no Youtube: https://www.youtube.com/playlist?list=PLjv17QYEBJPpd6nI-MXpIa4qR7prKfPQz

O código fonte do projeto utilizado está disponível no Github: https://github.com/rafaelzottesso/Curso-Django-2-Python-3

As apostilas que se encontram nos posts aqui no Blog também estão disponíveis.

Parte 01: Introdução ao Django e criação de páginas e templates https://docs.google.com/document/d/1V5wUiq1Oby-OBzwWG-53duH8EfSUN8xQwxIsuR7q-38/

Parte 02: Criação das classes (modelos) e das Views para inserir, alterar, excluir e listar objetos https://docs.google.com/document/d/1eriJCrhcfLRFgnWILKEL9BgSfDl7DmL89Lrs_p6uqfs/

Parte 03: Autenticação e controle de login/acesso https://docs.google.com/document/d/1SL98bmyw2j5PTQ3UNp95NfbYbeqWgZzk3vmNi6kMFt4/

Parte 04: “Ligação” dos registros/objetos com o usuário https://drive.google.com/open?id=1YOb_Ve99KfI073bLxDj4WQwlCeYNwNlncgBTwTyiHqU

Python e Django – Parte 02: Criação das classes (modelos) e das Views para inserir, alterar, excluir e listar objetos

Documentação das Views baseadas em classes

https://docs.djangoproject.com/pt-br/2.2/ref/class-based-views/generic-editing/

Criando um usuário administrador

Primeiro temos que criar um usuário que possa acessar o site de administração. Rode o seguinte comando:

$ python manage.py createsuperuser

Acesse: http://localhost:8000/admin/

Criando modelos

No arquivo models.py de alguma de suas aplicações/módulos, crie uma classe simples com os seguintes atributos:

from django.db import models
# Create your models here.
class Estado(models.Model):
sigla = models.CharField(max_length=2)
nome = models.CharField(max_length=50)

    def __str__(self):
        return self.sigla + " - " + self.nome
class Cidade(models.Model):
    nome = models.CharField(max_length=50)
    estado = models.ForeignKey(Estado, on_delete=models.PROTECT)

    def __str__(self):
        return self.nome + " - " + self.estado.sigla
class Pessoa(models.Model):
    nome = models.CharField(max_length=50, verbose_name="Qual seu nome?", help_text="Digite seu nome completo")
    nascimento = models.DateField(verbose_name='data de nascimento')
    email = models.CharField(max_length=100)
    cidade = models.ForeignKey(Cidade, on_delete=models.PROTECT)

    def __str__(self):
        return self.nome + ' - ' + str(self.nascimento)

A classe Cidade é uma extensão da classe “Model” que está dentro do pacote “models”. Dentro dela você pode criar vários atributos.

Existem diversos tipos (https://docs.djangoproject.com/pt-br/2.2/ref/models/fields/#field-types), alguns mais comuns são:

  • models.CharField(…) – Campo de texto comum (input do tipo texto)
  • models.TextField(…) – Campo de texto grande (textarea)
  • models.DateField(…) – vai ser um campo de data
  • models.DateTimeField(…) – vai ser um campo de data e hora
  • models.IntegerField(…) – valores inteiros
  • models.DecimalField(…) – valores decimais

Propriedades (https://docs.djangoproject.com/pt-br/2.2/ref/models/fields/#field-options):

  • max_length – tamanho máximo de caracteres.
  • verbose_name – Nome (label) que vai aparecer no formulário para identificar o campo/atributo. 
  • help_text – Texto extra de ajuda para ser mostrado com o “widget” do formulário. É útil para documentar mesmo que seu campo não seja usado em um formulário.
  • null – Se True, o Django pode usar valores nulos (null) no banco de dados. Padrão é False
  • blank – Se True, é permitido o campo estar em “branco” (vazio). O padrão é False.
  • default – O valor padrão para o campo.
  • unique – Se True, aquele atributo vai ser único no banco de dados. O padrão é False.

Para os campos de data, ainda deve-ser preencher dois atributos:

  • auto_now=True – Adiciona a data/hora toda vez que o objeto é salvo no banco. Geralmente, usado para verificar a última data/hora de modificação do objeto.
  • auto_now_add=True – Adiciona a data/hora toda vez que o objeto é criado no banco. Geralmente, usado para guardar a data que o objeto foi criado.

Campos relacionais (https://docs.djangoproject.com/pt-br/2.2/ref/models/fields/#foreignkey):

  • models.ForeignKey(Classe, on_delete=models.PROTECT) – chave estrangeira representada por um select no formulário. Precisa informar a classe do relacionamento e o modo de relação quando algum objeto da Classe for excluído (PROTECT, CASCADE, etc)

Opções adicionas de configuração de modelos (classe Meta): https://docs.djangoproject.com/pt-br/2.2/ref/models/options/

Sincronizando seu banco de dados com o models

Ao executar makemigrations, você está dizendo Django que você fez algumas mudanças em seus modelos (neste caso, você fez novas modificações) e que você gostaria que as alterações sejam armazenadas como uma migração. Para isso, execute:

$ python manage.py makemigrations seu_modulo_app

Agora rode o migrate para criar essas tabelas dos modelos no seu banco de dados:

$ python manage.py migrate

Acesse: http://localhost:8000/admin/

Ative os modelos criados no painel do administrador

No arquivo admin.py, importe todos os modelos do seu módulo e os ative no site administrativo:

from .models import *
admin.site.register(Estado)
admin.site.register(Cidade)
admin.site.register(Pessoa)

Acesse: http://localhost:8000/admin/

Criando uma método para cadastrar alguma coisa

No arquivo views.py é necessário importar todos os modelos, assim como fizemos no admin:

from .models import *

Também já iremos importar um método para redirecionar o usuário depois de efetuar o cadastro:

from django.urls import reverse_lazy

Por fim, vamos importar as Views (classes) que utilizaremos como “Pai” para nossas telas de cadastro (inserir, alterar e excluir):

from django.views.generic.edit import CreateView, UpdateView, DeleteView

Agora podemos criar nossas classes conforme o exemplo abaixo:

class EstadoCreate(CreateView):
model = Estado
fields = ['sigla', 'nome']
template_name = 'formulario.html'
success_url = reverse_lazy('index')
class CidadeCreate(CreateView):
model = Cidade
fields = ['nome', 'estado']
template_name = 'formulario.html'
success_url = reverse_lazy('index')

Agora basta fazer esse mesmo esquema para todos as classes que você deseja criar um formulário de cadastro no seu projeto.

Criando um formulário padrão para usar em diversos modelos

Você pode criar um arquivo na pasta “templates” chamado “formulario.html”, por exemplo. Dentro dele ajuste o layout como preferir e crie um formulário conforme abaixo:

<form method="post">
     {% csrf_token %}
     {{ form.as_p }}
     <button type="submit" class="btn btn-success">
            Cadastrar
     </button>
</form>

Não é necessário fazer validação de campos obrigatórios.

Criando a URL para cadastrar um modelo

No arquivo urls.py, crie um novo registro apontando para o método que você criou lá no views.py:

path('cadastrar/estado/', EstadoCreate.as_view(), name="cadastrar-estado"),
path('cadastrar/cidade/', CidadeCreate.as_view(), name="cadastrar-cidade"),

Utilizando o formulários do Bootstrap4

Existe um plugin (https://django-bootstrap4.readthedocs.io/en/latest/) que faz a geração do formulário e das mensagens de erro de validação conforme o Bootstrap 4. Para ativá-lo, vá no settings.py, procure por INSTALLED_APPS e adicione o módulo do plugin. Adicione, também, a constante no settings para definir o tipo padrão de templates logo depois do INSTALED_APPS.:

INSTALLED_APPS = [
    ...
    'crispy_forms',
]

CRISPY_TEMPLATE_PACK = 'bootstrap4'

No seu “formulario.html”, por exemplo, carregue o plugin depois de dar um load no static:

{% load crispy_forms_tags %}

No código HTML do formulário altere {{ form.as_p }} para {{ form|crispy }}

Agora atualize a página.

Criando uma tela para atualizar

O processo para atualizar registros é muito parecido com o CreateView. Portanto, altere apenas a classe que o método lá no views.py extende para UpdateView. O restante é a mesma coisa. Por exemplo:

class EstadoUpdate(UpdateView):
model = Estado
fields = ['sigla', 'nome']
template_name = 'formulario.html'
success_url = reverse_lazy('index')

Para criar a URL é necessário passar o ID do registro que será alterado e qual o tipo dele. Por padrão, todas as tabelas no Django criam um campo “id” do tipo inteiro. Então, crie uma nova url no seu urls.py:

path('atualizar/estado/<int:pk>/', EstadoUpdate.as_view(), name="atualizar-estado"),

Acesse http://localhost:8000/atualizar/estado/1/

Criando tela para excluir

Mesmo esquema, porém estendendo a classe DeleteView e não é necessário colocar o atributo “fields”:

class EstadoDelete(DeleteView):
model = Estado
template_name = 'formulario.html'
success_url = reverse_lazy('index')

Exemplo de url:

path('excluir/estado/<int:pk>/', EstadoDelete.as_view(), name="deletar-cidade"),

Usando o mesmo form, vai parecer que você está inserindo/salvando um registro. Então, crie um novo formulário personalizado com uma mensagem de exclusão:

<form method="post">
    {% csrf_token %}
    <p>Tem certeza que deseja excluir o registro "{{ object }}"?</p>
    <input type="submit" class="btn btn-danger" value="Sim, excluir.">
</form>

Listando objetos do banco de dados

https://docs.djangoproject.com/pt-br/2.2/ref/class-based-views/generic-display/

Importe o método ListView:

from django.views.generic.list import ListView

Crie um método no views.py que extende ListView e informe qual o modelo será usado e o template:

class EstadoList(ListView):
model = Estado
template_name = 'adocao/listar_estados.html'

Agora a tela de listagem você tem que fazer uma para cada por causa dos nomes dos atributos de cada modelo. Exemplo:

<table class="table table-striped">
    <tr>
        <th>ID</th>
        <th>Sigla</th>
        <th>Nome</th>
        <th>Opções</th>
    </tr>
    {% for estado in object_list %}
    <tr>
        <td>{{estado.pk}}</td>
        <td>{{estado.sigla}}</td>
        <td>{{estado.nome}}</td>
        <td>
            editar excluir
        </td>
    </tr>
    {% empty %}
    <tr>
        <td colspan="3">Nenhuma cidade cadastrada!</td>
    </tr>
    {% endfor %}
</table>

Por fim, a url para acessar a página criada:

path('listar/estados/', EstadoList.as_view(), name="listar-estados"),

Agora, para colocar os links para as páginas de “alterar” e “excluir”, modifique a tabela adicionando a URL no formato do Django, passando o “pk” como parâmetro:

<a href="{% url 'editar-estado' estado.pk %}" class="btn btn-warning">Editar</a>
<a href="{% url 'excluir-estado' estado.pk %}" class="btn btn-danger">Excluir</a>

Um parâmetro pode ser passado para uma URL da seguinte forma:

{% url 'editar-estado' objeto.atributo %}

Um link para adicionar um estado também pode ser adicionado no listar_estado.html:

<a href="{% url 'cadastrar-estado' %}">Adicionar estado</a>

Por fim, altere o EstadoCreate, EstadoUpdate e EstadoDelete para redirecionar o usuário para a lista e não mais para o index:

success_url = reverse_lazy("listar-estados")

Python e Django – Parte 01: Criação de um projeto, configuração e criação de uma URL


Trabalhar no ambiente virtual Django (Linux):
$ source /opt/virtualenv/django/bin/activate

Trabalhar no ambiente virtual Django (Windows):
workon django

Criando um projeto:
$ django-admin startproject Adocao

No Adocao/settings.py alterar configurações para o português do Brasil:

LANGUAGE_CODE = 'pt-br'
TIME_ZONE = 'America/Sao_Paulo'

Executar a criação de tabelas no banco e do conteúdo necessário para o gerenciamento do próprio Django

$ python manage.py migrate

Crie um Super Usuário para você (administrador):

$ python manage.py createsuperuser

Iniciar o servidor Django (padrão porta 8000)

$ python manage.py runserver

Se preferir, pode utilizar outra porta

$ python manage.py runserver 8080 (para definir, por exemplo, a porta 8080)

Outro IP

$ python manage.py runserver x.x.x.x:8000 (para rodar na rede local/Internet)

Ou de forma automática com seu IP da rede local

$ python manage.py runserver 0:8000 (para rodar na rede local/Internet)

Criando seu primeiro módulo (app) no projeto

$ python manage.py startapp cadastros

Registre seu app no seu projeto

É necessário ativar seu app no projeto lá no arquivo Adocao/settings.py. 

INSTALLED_APPS = [
'cadastros.apps.CadastrosConfig',
'django.contrib.admin',
...

Criando a primeira tela com classes (método mais utilizado desde a versão 2), conhecido como Class-based Views para realizar as tarefas do seu sistema, como inserir, cadastrar, exibir uma página, etc.

No arquivo Adocao/cadastros/views.py importe a classe genérica para exibir uma página simples e depois crie sua primeira classe para “renderizar” um template (HTML):

from django.views.generic import TemplateView
# Create your views here.

class IndexView(TemplateView):
    template_name = "index.html"

Como funcionam as classes dentro do “views”:

class NomeDaPaginaView(ClassePai):
template_name = "sua_pagina.html"

Criando um template em HTML para ser usado pelas Views

Primeiro altere a configuração do arquivo Adocao/Adocao/settings.py lá na configuração dos templates:

Procure por: ‘DIRS’: [],

E troque por: ‘DIRS’: [ os.path.join(BASE_DIR, ‘templates’) ],

Agora crie uma pasta chamada ‘templates‘ dentro da pasta da sua aplicação ‘animais’. Dentro dela você pode criar as páginas HTML que vai usar como suas telas (templates). Por exemplo: animais/templates/index.html

Definindo as URLS do seu sistema

Por padrão, os endereços ficam registrados nos arquivos urls.py. Cada app pode ter seus próprios endereços e o seu Projeto (Adocao) também pode ter as suas. 

Primeiro crie o arquivo “urls.py” dentro do seu app: animais/urls.py. 

Faça a importação da biblioteca que gerencia as urls e das classes/métodos criados nos views. 

from django.urls import path
from .views import IndexView

Crie uma url dentro do vetor de urls desse app. Os parâmetros são (nessa ordem): endereço, método/classe do views, nome da url no sistema.

urlpatterns = [
path('', IndexView.as_view(), name="index"),
]

Exemplo para criar novas URLS no seu projeto:

path('endereço_de_url/algo_mais/', NomeDaSuaView.as_view(), name="index"),

Adicione as URLS do app como URLS do projeto

Edite o arquivo Adocao/urls.py e inclua a biblioteca “include” depois de importar a biblioteca “path”.

from django.urls import path, include

Dentro da sua lista de urls, adicione um nome padrão para importar todas as suas urls do app:

urlpatterns = [
# Vai incluir todas as URLS do app animais neste padrão
path('', include('animais.urls')),
  path('admin/', admin.site.urls),
]

Se deixar ‘’ (aspas vazias) não precisa digitar nada na URL pra aceitar este padrão.

Definindo o diretório STATIC para armazenar seu CSS, imagens, JS, etc.

Dentro do diretório Adocao, raiz do projeto e não junto com settings.py, crie uma pasta chamada “static” e coloque lá todo seu css, js, imagens, etc.

Somente os arquivos HTML ficam dentro da pasta template de cada app porque eles podem ser exclusivos daquele app. A ideia da pasta static é disponibilizar as imagens, js e css para todos os apps e não somente um.

No arquivo Adocao/settings.py acrescente uma configuração para o Django procurar a pasta static na raiz do seu projeto (você pode ter várias pastas statics no seu PC):

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/2.2/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = [
    os.path.join(BASE_DIR, "static"),
]

Na primeira linha de todo arquivo HTML você precisa importar a pasta static do seu projeto:

{% load static %}

Agora é só usar conforme o exemplo abaixo para referenciar o local dela:

<img strc="{% static "img/example.jpg" %}" alt="My image"/>

Sempre em vez de colocar o caminho real, deve ser utilizado o esquema do static acima para referenciar algo que tem lá.

Reaproveitando um template

No Django é possível reutilizar um arquivo html (template) reescrevendo apenas algumas partes dele. Para isso, crie blocos de código no seu arquivo de modelo. Por exemplo:

modelo.html

<!DOCTYPE html>
<html lang="pt-br">
  <head>
    <meta charset="utf-8">
    …
  </head>
  <body>

  {% block menu %}
    <div class=”header”>
...
    </div>
  {% endblock %}

  {% block conteudo %}
    <div class=”container”>
...
    </div>
  {% endblock %}

  {% block rodape %}
    <div class=”footer”>
...
    </div>
  {% endblock %}

  </body>
</html>

No seu arquivo que deve ser igual a este anterior, pasta “estender” ele como se fosse uma herança e depois só é necessário reescrever os blocos que você quer alterar. Exemplo:

pagina_inicial.html

{% extends 'modelo.html' %}
{% block conteudo %}
  <div class="container">
    <div class="row">
      <div class="col-sm pt-5">
        <h3>Mah oe :D</h3>
       </div>
    </div>
  </div>
{% endblock %}

Instalação e utilização de ambientes virtuais no Windows

Este tópico tem como objetivo guiar a instalação e criação de ambientes virtuais (virtualenv) no Windows.

Considerando que você já tem o Python instalado, bem como as variáveis de ambiente e o “pip”, siga o procedimento a seguir.

– Instalar pacote para criação de ambientes virtuais
pip install virtualenv

– Instalar pacote para gerenciamento dos ambientes virtuais
pip install virtualenvwrapper-win

– Crie um ambiente virtual
mkvirtualenv nome_do_ambiente

– Ative o ambiente virtual recém criado
workon nome_do_ambiente

Pronto. Agora é só instalar os pacotes que deseja ter nesse ambiente virtual que você acabou de criar e ativar. Você pode ter quantos ambientes desejar e eles, por padrão, ficam dentro no diretório Envs dentro da pasta do usuário. Por exemplo: C:\Users\rafael\Envs

O procedimento a seguir serve para instalação do Django e de mais três coisas úteis para ele: o bootstrap, o braces para controle de acesso e o crispy-forms para geração de formulários conforme os padrões do bootstrap. Não esqueça de ativar o ambiente virtual que você deseja instalar os pacotes: workon nome_do_ambiente.

– Instalação dos pacotes no ambiente virtual desejado.
pip install django
pip install django-bootstrap4
pip install django-braces
pip install django-crispy-forms

Tutorial para Atualizar Django na Kinghost

Aleluia!

Começo este post com esta palavra porque deu muito trabalho conseguir (está certo que sou iniciante). Vou colocar aqui alguns passos pra você que deseja atualizar a versão no Django na sua hospedagem Kinghost.

No final do tópico deixei algumas referências que usei para construir este tutorial. O que fiz foi pegar a ideia de vários lugares, juntar tudo e fazer funcionar.

No momento, estou usando o Django versão 1.9.4. Vamos lá:

Primeiro crie o diretório .site-packages dentro de /home/usuário/app_wsgi/

cd apps_wsgi/ (se ela não existe, crie com o mkdir)
mkdir .site-packages
easy_install --install-dir=$PYTHONPATH virtualenv

Agora vamos criar um diretório para armazenar seu ambiente virtual. Crie a pasta .virtualenvs/ na raiz da sua hospedagem (/home/usuário/) e depois o ambiente. O ambiente virtual serve para você instalar versões de pacotes diferentes das atuais. Você pode ter vários ambientes virtuais instalados, cada um isolado do outro com suas versões de pacotes e aplicativos.

mkdir .virtualenvs
python apps_wsgi/.site-packages/virtualenv .virtualenvs/NOME_DO_AMBIENTE_VIRTUAL

Ative o ambiente para começar a instalar seus pacotes.

source .virtualenvs/NOME_DO_AMBIENTE_VIRTUAL/bin/activate

Até aqui, todo o conteúdo é original do https://gist.github.com/douglasmiranda/1232693.

Agora o nome do seu ambiente virtual vai aparecer entre parênteses no começo da linha. Isso quer dizer que você está usando seu ambiente virtual.

(SEU_AMBIENTE_VIRTUAL)14:51 ~ $ which pip
~/.virtualenvs/djpy/bin/pip

Agora sabemos que o pip usado é do ambiente virtual. Instale o Django na versão que preferir:

pip install django==1.9.4

Para verificar se foi instalado corretamente (meu ambiente virtual chama-se djpy) e qual a versão está instalada:

(djpy)-bash-4.1$ which django-admim.py
/usr/local/bin/django-admin.py
(djpy)-bash-4.1$ which django-admin
~/.virtualenvs/djpy/bin/django-admin

(djpy)-bash-4.1$ django-admin.py --version
1.8.3
(djpy)-bash-4.1$ django-admin --version
1.9.4

Repare que se eu colocar o .py no final do comando faz total diferença sobre o que você pretende fazer.

Crie seu projeto pelo painel administrativo da KingHost. Ele deve aparecer na pasta /home/usuário/app_wsgi/SEU_PROJETO. Agora você tem a pasta e um arquivo chamado /home/usuário/app_wsgi/SEU_PROJETO.wsgi.

Agora exclua seu projeto vazio e depois crie ele novamente com o mesmo nome na versão correta (cuidado com o .py):

(djpy)-bash-4.1$ rm -R SEU_PROJETO/
(djpy)-bash-4.1$ django-admin startproject SEU_PROJETO

Altere o conteúdo do arquivo SEU_PROJETO.wsgi para (lembrando que só coloquei maiúsculas para facilitar a visualização):

import os, sys

apache_configuration = os.path.realpath(os.path.dirname(__file__))
project = os.path.join(apache_configuration, 'SEU_PROJETO')

sys.path.append(apache_configuration)
sys.path.append(project)
sys.path.insert(0, "/home/usuário/.virtualenvs/SEU_AMBIENTE_VIRTUAL/lib/python2.7/site-packages")

os.environ['PYTHON_EGG_CACHE'] = '/home/usuário/apps_wsgi/.python-eggs'
os.environ['DJANGO_SETTINGS_MODULE'] = 'SEU_PROJETO.settings'

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

Use o comando touch para “recarregar” seu projeto no seu servidor:

(djpy)-bash-4.1$ touch SEU_PROJETO.wsgi

A fim de que os arquivos JS e CSS da admin do Django sejam servidos corretamente, você deverá configurar o parâmetro STATIC_ROOT (settings.py):

STATIC_ROOT='/home/usuário/www/static'
STATIC_URL='/static/'

Execute os comandos a seguir para coletar o conteúdo e recarregar a aplicação:

(djpy)-bash-4.1$ python manage.py collectstatic
(djpy)-bash-4.1$ touch familia.wsgi

Agora envie seu projeto usando um cliente FTP para a pasta /apps_wsgi/SEU_PROJETO/

Depois, sempre execute os comandos a seguir para coletar arquivos estáticos necessários e para recarregar a aplicação (dentro do diretório /home/usuário/apps_wsgi):

(djpy)-bash-4.1$ python manage.py collectstatic
(djpy)-bash-4.1$ touch SEU_PROJETO.wsgi

Lembre-se de sempre ativar o ambiente virtual desejado (para executar os comandos citados acima):

$ cd /home/usuário/apps_wsgi/
$ source .virtualenvs/NOME_DO_AMBIENTE_VIRTUAL/bin/activate

Referências: Suporte da Kinghost
https://gist.github.com/douglasmiranda/1232693
https://help.pythonanywhere.com/pages/VirtualEnvForNewerDjango