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.
Documentação dos Sistemas de Autenticação do Django
Views de Autenticação (Login, Logout, Troca de senha, Reset de senha, etc)
Crie um novo app
Vamos separar do nosso módulo principal o gerenciamento de usuários para não ficar muita coisa em um módulo só. Para isso, crie um app chamado “usuarios”:
python manage.py startapp usuarios
Crie um arquivo de urls
Dentro do módulo novo, crie um arquivo “urls.py” com o seguinte código (o básico para criar e usar as urls):
from django.urls import path from django.contrib.auth import views as auth_views urlpatterns = [ # Aqui vão suas urls ]
Crie o diretório dos templates
Dentro do app “usuarios”, crie também uma pasta “templates” com uma pasta “usuarios” dentro dela.
Utilizando as Views existentes para Login
Existe uma View pronta já para funcionar como tela de login, basta criar uma url e apontar para ela, indicando qual o template será usado para fazer o login. É possível já usar um template que existe ou criar um novo só para login.
E agora crie o template login.html dentro do módulo “usuarios” com o seguinte conteúdo (que pode variar de acordo com o seu e no geral é igual algum form.html que você já tem):
{% extends 'adocao/base.html' %}
{% load static %}
{% load crispy_forms_tags %}
{% block header %} {% endblock %}
{% block container %}
<div class="container py-5">
<div class="row mt-5">
<div class="col-lg">
<h3>{{ titulo }}</h3>
</div>
</div>
<div class="row">
<div class="col-lg-5">
<form method="post">
<!-- Todo formulário tem que ter essa validação -->
{% csrf_token %}
<!-- Gera o formulário -->
{{ form|crispy }}
<button type="submit" class="btn btn-primary">
Entrar
</button>
</form>
</div>
</div>
</div>
{% endblock %}
Ative o módulo no settings.py
Agora é necessário ativar o novo módulo no settings.py para que ele funcione normalmente. Para isso, dentro de “INSTALLED_APPS” adicione (antes de fechar o vetor [ …. ]):
'usuarios.apps.UsuariosConfig',
Importe as URLSpara o projeto padrão
No arquivo “urls.py” que está junto com settings.py, importe o arquivo de urls que foi criado lá no módulo “usuarios”:
Por enquanto fizemos apenas a autenticação. Agora será necessário informar as páginas que só podem ser acessadas se o usuário fizer login.
Redirecionar o usuário depois do login
Por padrão, o usuário vai ser redirecionado para http://127.0.0.1:8000/accounts/profile/ depois de fazer login, mas não temos esse endereço. Podemos alterar a URL que o usuário será redirecionado após o login (LOGIN_REDIRECT_URL) e a URL que o usuário vai ver se tentar acessar alguma página que não tem login (LOGIN_URL). Configure também pra onde o usuário vai depois de fazer logout (LOGOUT_REDIRECT_URL). Adicione no settings.py essas duas constantes e o nome da URL:
# Nome da URL em que o usuário será redirecionado # https://docs.djangoproject.com/en/2.1/ref/settings/#auth LOGIN_REDIRECT_URL = 'index' LOGIN_URL = 'login' LOGOUT_REDIRECT_URL = 'login'
Definindo as páginas que precisam de login para serem acessadas
Lá nos seus arquivos “views.py”, independente do módulo, importe a classe que vai fazer as páginas requisitarem a autenticação para serem exibidas:
from django.contrib.auth.mixins import LoginRequiredMixin
Criando as heranças
Agora, nas suas classes/métodos dentro do views.py basta criar uma herença para LoginRequiredMixin e adicionar o atributo login_url = reverse_lazy(‘login’).
Exemplo:
class CidadeUpdateView(LoginRequiredMixin, UpdateView): login_url = reverse_lazy('login') ...
Atenção: O LoginRequiredMixin precisa ser importado antes de outras coisas e o método reverse_lazy tem que estar importado (from django.urls import reverse_lazy).
Criando uma tela para o usuário alterar sua senha
Também existe uma View que faz todo esse trabalho para nós (PasswordChangeView). Ela é semelhante à url de login e precisamos passar mais um parâmetro pra ela: “success_url”, que nada mais é do que para onde o usuário vai ser redirecionado após alterar a senha.
Para isso, vá no “urls.py” do módulo “usuarios” e importe o “reverse_lazy” no início do arquivo:
Pronto, basta acessar http://127.0.0.1:8000/alterar-minha-senha/ que você vai ver o formulário para alteração de senha. A View utiliza o mesmo formulário de Login, por isso usamos o “extra_context” para enviar o título da página.
Criar link para usuário
Agora basta criar mais um link no seu menu para facilitar a troca de senha:
Controle de acesso ao conteúdo diretamente nos templates
Nos templates também é importante verificar se o usuário fez o login para poder mostrar algumas coisas ou não. Isso é, basicamente, simples e envolve usar um if/else para verificar a autenticação.
Primeiro vamos no nosso menu para esconder alguns links. Vá no seu arquivo base do template (ex. base.html) e faça algo parecido com seu menu:
{% if request.user.is_authenticated %} <!-- Links/Conteúdo exibidos apenas para usuários logados --> {% endif %}
Mostrando dados do usuário
Lá nos templates é possível mostrar algumas informações do usuário por meio da instrução “request.user.atributo”. Exemplos:
Mostrar o primeiro nome: {{ request.user.first_name }}
Este framework permite fazer o controle de acesso à determinadas URL de acordo com o grupo em que os usuários pertencem.
Documentação do plugin/framework:
Controle de acesso por grupo
Instalar o plugin (aqui no IFPR já está instalado)
pip install django-braces
Para ver os grupos que você tem ou para criar mais, acesse:
Você pode adicionar um grupo pelo próprio Django Admin. Vamos criar dois grupos:
Administrador
Usuário
Quando criamos um usuário pelo comando (python manage.py createsuperuser), esse usuário passa a ter acesso total ao nosso projeto. É possível remover/adicionar o status de superusuário ao editar algum usuário pelo Django Admin.
Definindo que uma URL/View nossa precisa ter um usuário que pertence a um determinado grupo
Vá no seu arquivo “adocao/views.py” e importe o módulo para controle de acesso por grupo:
from braces.views import GroupRequiredMixin
Agora, basta fazer uma herança nas suas views para GroupRequiredMixin e criar o atributo group_required na sua classe. É importante notar que a primeira herança deve ser do GroupRequiredMixin. Por exemplo:
No nosso projeto, vamos fazer com que os cadastros de Cidade, Estado, Tipo e Raca sejam somente visualizados pelo administrador (inserir, alterar, excluir e listar).
class EstadoCreate(GroupRequiredMixin, LoginRequiredMixin, CreateView): group_required = u"Administrador" ...
Ajustar o template de login para redirecionar usuários autenticados
Só vamos mostrar o form se o usuário não estiver autenticado.
{% if request.user.is_authenticated %} <h4 class="mt-4 text-danger">Você não pode fazer isso!</h4> Redirecionando para a página inicial em 5 segundos... <meta http-equiv="Refresh" content="5; url={% url 'index' %}" /> {% else %} <form method="post"> <!-- Todo formulário tem que ter essa validação --> {% csrf_token %} <!-- Gera o formulário --> {{ form|crispy }} <button type="submit" class="btn {{ classe }}"> {{ botao }} </button> </form> {% endif %}
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)
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.
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)
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 omigrate para criar essas tabelas dos modelos no seu banco de dados:
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:
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:
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
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>
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:
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.
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):
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:
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:
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
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.
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):
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):