Python

O que é Flask?

Escrito em Python e disponível sobre a licença BSD (Licença de código aberto), o Flask é um micro-framework multiplataforma que provê um modelo simples para o desenvolvimento web.

Flask - Fundamentos
Curso de Flask - Fundamentos
CONHEÇA O CURSO

Mas afinal, o que é um Micro-framework?

Já falamos aqui no blog o que é um micro-framework, mas para relembrar:

Um Micro-Framework são Frameworks modularizados que possuem uma estrutura inicial muito mais simples quando comparado a um Framework convencional.

Podemos dizer que o micro-framework é uma versão minimalista destes frameworks, sendo bastante utilizado para criação de microsserviços, como APIs RESTful.

No artigo anterior, fizemos uma comparação de objetos do mundo real para exemplificar o funcionamento de um micro-framework:

Pense em um Micro-Framework como uma peça de lego. Inicialmente, um projeto criado com o micro-framework possui apenas o básico para funcionar, (normalmente, sistema de rotas), porém, ao decorrer do projeto, podem haver necessidades para utilização de outros recursos como, conexão de banco de dados, sistemas de templates, envio de email, etc. A partir desta necessidade, novas bibliotecas são “encaixadas” no projeto, como uma estrutura de lego.

De volta ao Flask…

Lançado em 2010 e desenvolvido por Armin Ronacher, o Flask é um micro-framework destinado principalmente a pequenas aplicações com requisitos mais simples, como por exemplo, a criação de um site básico.

Possui um núcleo simples e expansível que permite que um projeto possua apenas os recursos necessários para sua execução (conforme surja a necessidade, um novo pacote pode ser adicionado para incrementar as funcionalidades da aplicação).

Características do Flask

  • Simplicidade: Por possuir apenas o necessário para o desenvolvimento de uma aplicação, um projeto escrito com Flask é mais simples se comparado aos frameworks maiores, já que a quantidade de arquivos é muito menor e sua arquitetura é muito mais simples.

  • Rapidez no desenvolvimento: Com o Flask, o desenvolvedor se preocupa em apenas desenvolver o necessário para um projeto, sem a necessidade de realizar configurações que muitas vezes não são utilizadas.

  • Projetos menores: Por possuir uma arquitetura muito simples (um único arquivo inicial) os projetos escritos em Flask tendem a ser menores e mais leves se comparados a frameworks maiores.

  • Aplicações robustas: Apesar de ser um micro-framework, o Flask permite a criação de aplicações robustas, já que é totalmente personalizável, permitindo, caso necessário, a criação de uma arquitetura mais definida.

Exemplo de uma aplicação Flask

Abaixo podemos ver um exemplo de uma aplicação em Flask. Podemos notar o quão simples criar uma aplicação web pode ser:

from flask import Flask
app = Flask(__name__)

@app.route("/")
def index():
    return 'Bem-vindo a TreinaWeb!'

if __name__ == "__main__":
    app.run()

Podemos concluir que…

O Flask é uma excelente alternativa para o desenvolvimento de aplicações utilizando o Python. Ele é o principal concorrente do Django, apesar de ser considerado um micro-framework.

Aqui no blog da TreinaWeb fizemos um comparativo entre o Django e o Flask, caso esteja em dúvida em qual framework utilizar, vale a pena a leitura.

Criando o primeiro projeto Django

No artigo anterior vimos como configurar nosso ambiente de desenvolvimento para a criação de projetos Python e Django. Agora, com o ambiente devidamente configurado, veremos como criar o primeiro projeto Django utilizando as ferramentas instaladas 🙂

Criando projeto

O primeiro passo para criarmos nosso projeto com Django é abrir o PyCharm. Ao fazer isso, veremos a seguinte tela:


Dentre as três opções disponíveis, selecionaremos a “Create New Project” para criar o primeiro projeto do PyCharm. Ao fazer isso, seremos redirecionados para a seguinte tela:


Aqui, definimos a localização do projeto e onde será armazenada a virtualenv do mesmo. Se você não sabe o que é uma virtualenv, recomendo a leitura deste artigo.

Costumo armazenar a virtualenv de cada projeto em seu próprio diretório. Assim, cada projeto possuirá sua virtualenv isolada 🙂

Django - Fundamentos
Curso de Django - Fundamentos
CONHEÇA O CURSO

Depois de informar a localização do projeto e criar a virtualenv, podemos clicar em “Create” para que o PyCharm crie o diretório do projeto. No fim do processo, será exibida a seguinte tela:

Instalando o Django

Com o projeto do PyCharm criado, o primeiro passo é instalar o Django em nossa virtualenv. Para isso, o PyCharm possui uma interface gráfica que auxilia todo este processo, localizada em File > Settings > Project Interpreter (se você está utilizando o Windows ou Linux) ou PyCharm > Preferences (se você está utilizando o macOS).



É nesta janela que poderemos adicionar os pacotes à nossa virtualenv. Para isso, clicamos no botão “+” localizado no canto inferior esquerdo da janela, que exibirá uma tela para buscarmos pelo pacote desejado:


Nesta janela, buscamos pelo pacote “Django” e clicamos em “Install Package”. Após isso, o PyCharm (utilizando o PIP) vai baixar o pacote selecionado e instalar na virtualenv do projeto. Ao finalizar este processo, podemos fechar a janela e notaremos que o pacote foi instalado com sucesso:


Agora, voltando ao PyCharm, precisamos criar o projeto utilizando o Django. Para isso, no terminal integrado da IDE, digitamos o seguinte comando:

django-admin startproject primeiro_projeto

O comando acima irá criar um projeto Django chamado “primeiro_projeto” com a seguinte estrutura de pastas:


Basicamente, há quatro arquivos no projeto criado, onde a função de cada um deles pode ser vista abaixo:

  • settings.py: Arquivo para armazenar as configurações gerais do projeto, como os pacotes a serem utilizados, configurações de bancos de dados, localização de arquivos estáticos, etc.
  • urls.py: Arquivo para armazenar as rotas que serão utilizadas no projeto. Este arquivo armazenará as rotas do projeto em geral, é recomendável que cada aplicação do projeto possua um arquivo de rotas específico… Mas não se preocupe, falaremos sobre apps no próximo artigo 🙂
  • wsgi.py: Interface simples e universal para troca de informações entre servidores web e aplicações criadas com Python.
  • manage.py: Arquivo responsável por gerenciar o projeto como um todo. É, basicamente, um CLI para projetos Django.

Executando servidor Django

Com o projeto criado, podemos executar seu servidor de desenvolvimento para verificar se tudo está conforme planejado. Para isso, ainda no terminal do PyCharm, utilizamos o seguinte comando:

python manage.py runserver

Ao executar o comando acima, o servidor do Django será inicializado e poderemos acessá-lo através da rota http://127.0.0.1:8000, conforme é retornado no terminal:


Ao executar a rota citada acima em um navegador, teremos a seguinte página como resposta:


Esta (linda) página indica que a instalação foi feita corretamente e que estamos prontos para desenvolver nossa primeira aplicação com o Django o/

Ficou animado? Então fica ligado que no próximo artigo veremos como criar uma aplicação com o Django e iniciarmos seu desenvolvimento 😀

Até lá!!

Configurando ambiente de desenvolvimento para projetos Django

O Django é um ótimo framework para o desenvolvimento de aplicações com um grande reaproveitamento de código e facilidade de aprendizado. Segundo o Stack Overflow Trends, o Django é, atualmente, um dos principais frameworks full stack do mercado, sendo mais pesquisado que o Laravel e Spring. Pensando nisso, veremos neste artigo como dar nossos primeiros passos com o Django e criar nosso primeiro projeto.

O que é o Django?

Já falamos em outro artigo o que é e como funciona o Django. Basicamente, ele é um framework escrito em Python para desenvolvimento de aplicações web muito popular e com uma comunidade incrível. Não vamos entrar em detalhes mais específicos sobre o funcionamento básico do Django, já que isto pode ser visto em um artigo que já escrevemos, caso você tenha alguma dúvida, é extremamente recomendado que o leia antes de iniciar seus estudos com o framework 🙂

Django - Fundamentos
Curso de Django - Fundamentos
CONHEÇA O CURSO

Ambiente de desenvolvimento

Basicamente, o Django precisa apenas do Python instalado na máquina para que consigamos criar e executar um projeto. Porém, há três outras ferramentas que você deve considerar em seu ambiente de desenvolvimento, como veremos a seguir.

Sendo assim, o primeiro passo é instalar o Python em nossa máquina. Por ser multi-plataforma, o Python funcionará em qualquer sistema operacional que você utilizar (Windows, Linux ou macOS). Seu download pode ser feito na página oficial da ferramenta. Caso você utilize o Linux ou macOS, você já deve possuir o Python instalado em seu computador. Para verificar esta existência, podemos abrir o terminal e ditarmos o seguinte comando:

python --version

Ao executarmos o comando acima, teremos o seguinte retorno:


Lembrando que podem haver duas versões do Python instalados em sua máquina, então você pode especificar a versão que você deseja verificar a instalação (Python 2 ou Python 3).

No Windows, a instalação é simples (next > next > next > finish), tendo apenas que se atentar em marcar a opção de adicionar o Python ao PATH do sistema:

Feito isso, o Python será instalado e configurado automaticamente no Windows.

PIP, PyCharm e Virtualenv

Com o Python instalado, podemos falar das outras três ferramentas que considero essenciais para o desenvolvimento de aplicações Django: o PIP, PyCharm e Virtualenv.

O PIP é, basicamente, um gerenciador de pacotes para projetos Python. Muito utilizado quando precisamos instalar pacotes externos em nossos projetos. Já temos um ótimo artigo sobre como funciona e como instalar o PIP em nosso ambiente. Recomendo, fortemente, a leitura 🙂

Já o PyCharm é a principal IDE para desenvolvimento de aplicações Python do mercado. Desenvolvido pela Jetbrains, o PyCharm é multi-plataforma e possui as versões Professional e Community.


A instalação do PyCharm segue o velho padrão (next > next > finish) e, com certeza, você vai se encantar com todos os recursos dessa IDE no desenvolvimento de suas aplicações.

A última ferramenta é a virtualenv. Um problema muito comum é quando precisamos utilizar diversas versões de uma mesma biblioteca em diferentes projetos Python. Isso pode acarretar em conflitos entre as versões e muita dor de cabeça para o desenvolvedor. Para resolver este problema, o mais correto é a criação de um ambiente virtual para cada projeto.

Para criar estes ambientes virtuais, podemos utilizar uma virtualenv. Também possuímos aqui no blog um artigo sobre como funciona uma virtualenv no Python e como instalá-la em nossa máquina.

Ambiente configurado, e agora?

Com todas as ferramentas instaladas no computador, já estamos aptos a desenvolver primeiros projetos com o Django. Para isso, veremos no próximo artigo como criar o primeiro projeto com Django e qual a funcionalidade de cada arquivo existente em sua arquitetura 🙂

Até lá!!

Utilizando Choices no Django ORM

Na construção de um formulário, há casos em que precisamos de um campo para armazenar determinadas opções para um atributo. Um exemplo claro deste caso é o armazenamento do sexo de um usuário, que só deve permitir uma determinada lista de opções (masculino, feminino, outro).
Para estes casos, o Django ORM permite que criemos uma lista com as possíveis opções que deverão ser selecionadas, evitando que o usuário possa digitar qualquer valor naquele campo.
Sendo assim, neste artigo veremos como trabalhar com choices no Django ORM.

Criando choices no models.py

Para criar uma lista de possíveis opções no Django ORM, precisamos definir quais serão estas opções e a qual chave ela pertence. Por exemplo, se quisermos criar uma lista de opções para o campo sexo, determinamos o seguinte conteúdo no arquivo models.py do nosso projeto:

class Cliente(models.Model):
    SEXO_CHOICES = (
        ("F", "Feminino"),
        ("M", "Masculino"),
        ("N", "Nenhuma das opções")
    )

    nome = models.CharField(max_length=100, null=False, blank=False)
    sexo = models.CharField(max_length=1, choices=SEXO_CHOICES, blank=False, null=False)
    data_nascimento = models.DateField(null=False, blank=False)
    email = models.EmailField(null=False, blank=False)


    def __str__(self):
        return self.nome
Django - Banco de dados com Django ORM - Parte 1
Curso de Django - Banco de dados com Django ORM - Parte 1
CONHEÇA O CURSO

Note que precisamos criar a variável SEXO_CHOICES e determinar quais as opções que um sexo poderá exercer. Depois disso, criamos o campo sexo em nosso model e determinamos que as opções disponíveis para este campo estão definidas na variável SEXO_CHOICES. Com isso, sempre que o formulário para cadastro (ou edição) de um cliente for submetido, o Django irá verificar se uma das opções foi selecionada. Caso positivo, libera a requisição, caso negativo, alerta ao usuário que apenas estas opções são permitidas a serem selecionadas.

Um outro ponto positivo para o uso do choices é que só precisamos armazenar a chave que irá identificar cada sexo, assim, economizamos um certo espaço no banco de dados, já que só será necessário armazenar um caractere (F, M ou N), não o nome do sexo (Feminino, Masculino ou Nenhuma das opções).

O que é o SQLAlchemy?

Desenvolvido para a linguagem de programação Python, o SQLAlchemy é um framework de mapeamento objeto-relacional SQL (ORM) de código aberto sobre a licença MIT.

Mas afinal, o que é o ORM?

Mapeamento objeto-relacional ou simplesmente ORM é uma técnica de programação que auxilia na conversão de dados entre banco de dados relacionais e linguagens de programação que são orientadas à objetos.

A utilização deste Framework faz com que o programador reduza a programação de acesso ao banco de dados, desta forma, obtendo uma produtividade significativa no desenvolvimento de suas aplicações.

Ou seja, ORM trata-se de um Framework que visa auxiliar na redução da impedância, realizando todas as conversões necessárias entre o modelo relacional e o modelo orientado a objetos de maneira automática, geralmente da seguinte forma:

  • Cada classe é interpretada com uma tabela;
  • Cada linha de uma determinada tabela, junto com seu relacionamento é tratada como instância do objeto relacionado à tabela em questão.

Sua utilização também visa retirar a necessidade do desenvolvedor de software em se preocupar com a linguagem SQL (geração dos comandos SQL) e com as conversões necessárias entre os diferentes tipos de dados, já que tudo isto fica a cargo do Framework ORM.

Conseguimos utilizar banco de dados relacionais por meio de objetos escritos em Python, não se preocupando em como este BD está funcionando (relações, campos, etc), apenas mapeando sua estrutura.

Python - SQLAlchemy ORM
Curso de Python - SQLAlchemy ORM
CONHEÇA O CURSO

Voltando ao SQLAlchemy…

Lançado em fevereiro de 2006 tendo como autor Michael Bayer, o SQLAlchemy encontra-se na versão 1.3.6 liberada em 21 de julho de 2019. É um Framework multiplataforma que rapidamente se tornou umas das ferramentas de mapeamento objeto-relacional mais utilizada na comunidade Python, linguagem para qual foi desenvolvida.

O SQLAlchemy é um ORM completo, criado com Python para desenvolvedores de aplicativos, que fornece flexibilidade total do SQL, obtendo um conjunto completo de padrões de persistência de nível corporativo bem conhecidos, que são projetados para acesso a banco de dados eficientes e de alto desempenho.

Com ele, o desenvolvedor não necessita se preocupar com a utilização de códigos SQL no desenvolvimento de aplicações, já que todo acesso ao banco de dados é feito utilizando código Python.

Além disso, o SQLAlchemy possui todas as garantias de segurança necessárias para proteger as aplicações de ataques ao seus bancos de dados, garantindo, assim, a criação de aplicativos simples e seguros.

Aqui no blog possuímos um artigo sobre “Principais tipos de ataques a aplicações web”.

Exemplos de consultas com SQLAlchemy

Como dito anteriormente, com o SQLAlchemy não precisamos nos preocupar com a criação de códigos SQL, já que tudo é feito inteiramente utilizando Python tornando, assim, a aplicação mais simples, como podemos ver nos exemplos abaixo:

Consulta de dados:

alldata = session.query(Filme).all()

O código acima pode ser convertido na seguinte instrução SQL:

SELECT * FROM Filme

Inserção de dados:

f1 = Filme("Star Trek", 2009)
session.add(f1)

O código acima pode ser convertido na seguinte instrução SQL:

INSERT INTO Filme (nome, ano) VALUES ("Star Trek", 2009)

Com isso, podemos ver o quão simples e legível se torna nosso código, não misturando comandos SQL com código Python e mantendo a leitura muito mais eficiente.

Para maiores informações sobre sua documentação, download e notícias sobre o SQLAlchemy, basta acessar seu site.

Personalizando a chave primária no Django ORM

Por padrão, o ORM do Django cria, para cada tabela, um campo chamado id e é ele quem identifica, unicamente, os registros no banco de dados. Porém, muitas vezes, precisamos que este campo possua outro nome (ou até outro tipo)… E é isso que veremos neste artigo.

Django - Banco de dados com Django ORM - Parte 1
Curso de Django - Banco de dados com Django ORM - Parte 1
CONHEÇA O CURSO

Alterando nome e tipo da chave primária no Django ORM

Como exemplo para este artigo, vamos utilizar um model simples, com apenas alguns campos, conforme podemos ver abaixo:

class Pessoa(models.Model):
    nome = models.CharField(max_length=40, null=False, blank=False)
    email = models.EmailField(null=False, blank=False)

    def __str__(self):
        return self.nome

Ao realizar a migração, a seguinte estrutura será criada no banco de dados:

Podemos notar que, apesar de não definir nenhum campo com o nome id, o Django o criou automaticamente. Por padrão, este campo é do tipo int(11), não permite dados nulos e é utilizado para armazenar a chave primária da tabela. Porém, caso necessário, podemos alterar a estrutura deste campo facilmente utilizando o Django.

Para isso, a única coisa que precisamos fazer é criar um campo que será utilizado como primary_key no model do nosso projeto, como podemos ver abaixo:

class Pessoa(models.Model):
    id_personalizado = models.CharField(max_length=20, primary_key=True)
    nome = models.CharField(max_length=40, null=False, blank=False)
    email = models.EmailField(null=False, blank=False)

    def __str__(self):
        return self.nome

Sendo assim, podemos notar que a única coisa necessária para alterar a chave primária de uma tabela é determinar o atributo primary_key=True e, com isso, este campo será utilizado como chave primária no banco de dados:

Concluindo

Apesar de possuir diversas configurações padrões, o ORM do Django permite a personalização de várias delas. Neste artigo vimos o quão simples é alterar o nome da chave primária de um determinado model.

Enviando email com Python e SMTP

O envio de emails é a melhor forma para se comunicar com os usuários de uma aplicação. Além de ser gratuito (na maioria das vezes), é seguro e muito utilizado em todo o mundo.

Pensando nisso, veremos neste artigo como enviar e-mails em aplicações Python utilizando SMTP.

Configurando servidor gmail

Em nosso exemplo, veremos como enviar um email utilizando o serviço do gmail (pois ele é o mais utilizado no mundo). Porém, antes de iniciar o desenvolvimento do nosso projeto, precisamos criar um token para ser utilizado como password, caso você utilize o recurso de autenticação em duas etapas (recurso que só permite que seu usuário seja autenticado caso você o libere em seu smartphone) ou não quer que sua senha seja utilizada em aplicações não seguras.

Criando token

Para criar um token que será utilizado como senha em nossa aplicação, precisamos ir até o seguinte link: https://security.google.com/settings/security/apppasswords.

Na página, vamos selecionar a opção “Outro” para definir um nome para nosso projeto. Em seguida, determinamos o nome da aplicação e geramos o token:

Ao clicar em “GERAR”, seremos redirecionados para a tela de login da nossa conta. Ao inserir o email e senha, clicamos em “Próxima” e nosso token será gerado com sucesso:

É essa “senha de app” que vamos utilizar para autenticar com nosso gmail na aplicação (lembre-se de copiá-la).

Criando script para envio de email

Nosso script será bem simples. Basicamente, vamos informar o email e senha (conforme gerada no tópico anterior) da conta que será usada para enviar o email, o destinatário e o conteúdo do email. Sendo assim, o código final será o seguinte:

import smtplib

server = smtplib.SMTP_SSL('smtp.gmail.com', 465)
server.login("seu_email@gmail.com", "senha_gerada_topico_anterior")
server.sendmail(
  "remetente@gmail.com",
  "destinatario@gmail.com",
  "Conteúdo da mensagem")
server.quit()

Basicamente, o código acima irá criar uma conexão com o serviço de SMTP do gmail por meio da porta 456, realizar o login com as credenciais do usuário e enviar o email conforme os parâmetros enviados pelo método sendmail(). Ao concluir o processo, finalizamos o servidor e o email deve chegar no destinatário.

Sendo assim, ao executar o código acima (você pode utilizar qualquer editor de texto, IDE ou terminal), o email será enviado com sucesso, chegando até o destinatário:

Conclusão

Neste artigo vimos o quão simples é enviar um email utilizando Python. Claro que há várias melhorias que podemos fazer (adicionar o assunto do email, enviar um código HTML como conteúdo do email), mas isso nós veremos em um outro artigo 🙂

Implementando autenticação no Django – Parte 2

Continuando a implementação do módulo de autenticação em uma aplicação Django que iniciamos no artigo “Implementando autenticação no Django – Parte 1“, veremos neste artigo como implementar os métodos de logout, alterar senha do usuário e proteger páginas para que só sejam acessadas por usuários devidamente autenticados.

Logout

A principal função do método de logout é remover a sessão do usuário que está logado na aplicação, fazendo com que este login não esteja mais ativo no sistema. Assim como o método de login, o Django possui, em seu módulo de autenticação, o método para deslogar usuários. Para implementá-lo, basta criar um método no arquivo views.py com o seguinte conteúdo:

def deslogar_usuario(request):
    logout(request)
    return redirect('index')

Basicamente, o médoto deslogar_usuario recebe uma requisição e remove o usuário que está logado dela. Simplesmente assim 🙂

Agora, para acessar o método de deslogar_usuario, precisamos criar sua rota no arquivo urls.py da aplicação:

from django.contrib import admin
from django.urls import path, include
from .views import *

urlpatterns = [
    path('logar_usuario', logar_usuario, name="logar_usuario"),
    path('deslogar_usuario', deslogar_usuario, name="deslogar_usuario"),
    path('cadastrar_usuario', cadastrar_usuario, name="cadastrar_usuario"),
    path('index', index, name="index"),
]

Com isso, ao acessar a rota http://localhost:8000/deslogar_usuario, a sessão será destruída e o usuário deslogado do nosso projeto.

Alterar senha do usuário

Uma outra funcionalidade importante para um sistema de autenticação é o método para alterar senha do usuário logado. Com o Django, esta implementação é bem simples.

Primeiro, vamos criar um método alterar_senha no arquivo views.py do projeto com o seguinte conteúdo:

def alterar_senha(request):
    if request.method == "POST":
        form_senha = PasswordChangeForm(request.user, request.POST)
        if form_senha.is_valid():
            user = form_senha.save()
            update_session_auth_hash(request, user)
            return redirect('index')
    else:
        form_senha = PasswordChangeForm(request.user)
    return render(request, 'alterar_senha.html', {'form_senha': form_senha})

Basicamente, este método irá criar um PasswordChangeForm vazio para que o usuário que estiver logado digite as informações necessárias para alteração de senha (senha antiga, nova senha e confirmação da nova senha). Depois que o usuário submeter o formulário, verificamos se ele é válido e, caso positivo, alteramos a senha do usuário com o método update_session_auth_hash e redirecionamos para a página index da aplicação.

Para que o usuário consiga digitar as informações necessárias para alterar sua senha, criaremos um template chamado alterar_senha no diretório templates da nossa aplicação. Ele é bem simples, apenas renderizamos os inputs necessários para esta funcionalidade:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Alterar senha</title>
</head>
<body>

<form method="post">
    {% csrf_token %}

    <div class="form-group">
        {{form_senha.old_password.errors}}
        <label>Senha antiga: </label>
        {{form_senha.old_password}}
    </div>

    <div class="form-group">
        {{form_senha.new_password1.errors}}
        <label>Nova senha: </label>
        {{form_senha.new_password1}}
    </div>

    <div class="form-group">
        {{form_senha.new_password2.errors}}
        <label>Confirmação de senha: </label>
        {{form_senha.new_password2}}
    </div>

    <div class="form-group">
        <input type="submit" value="Alterar" class="btn btn-primary">
    </div>
</form>

</body>
</html>

Por fim, precisamos criar a rota responsável por executar o método alterar_senha. Para isso, no arquivo urls.py da aplicação, adicionamos a seguinte linha no array urlpatterns:

    path('alterar_senha/', alterar_senha, name='alterar_senha'),

Com isso, ao acessar a rota http://localhost:8000/alterar_senha, veremos o seguinte resultado:

É por meio desta página que o usuário poderá alterar sua senha na aplicação.

Proteger páginas

Sabemos que a principal vantagem de implementar a autenticação em nossas aplicações é a de proteger páginas e recursos para que apenas usuários devidamente autenticados possam acessá-las. Para isso, só precisamos adicionar o decorator login_required nos métodos que queremos proteger:

@login_required(login_url='/logar_usuario')
def index(request):
    return render(request, 'index.html')

@login_required(login_url='/logar_usuario')
def deslogar_usuario(request):
    logout(request)
    return redirect('index')

@login_required(login_url='/logar_usuario')
def alterar_senha(request):
    if request.method == "POST":
        form_senha = PasswordChangeForm(request.user, request.POST)
        if form_senha.is_valid():
            user = form_senha.save()
            update_session_auth_hash(request, user)
            return redirect('index')
    else:
        form_senha = PasswordChangeForm(request.user)
    return render(request, 'alterar_senha.html', {'form_senha': form_senha})

Agora, ao tentar acessar as páginas para alterar senha, deslogar usuário e index, o Django irá verificar se existe algum usuário logado e, caso contrário, redirecionará para a página de login.

Conclusão

Nesta série de artigo, vimos o quão fácil é implementar os principais recursos de autenticação com o Django. A autenticação é a melhor forma de garantir que os recursos de um projeto só sejam acessados por usuário previamente cadastrados e autenticados, garantindo uma maior segurança do projeto.

Lembrando que o código-fonte deste projeto se encontra neste repositório

Implementando autenticação no Django – Parte 1

A autenticação é uma das principais funcionalidades em um sistema. É com ela que protegemos as funcionalidades de uma aplicação e permitimos que estas só sejam acessadas por usuários cadastrados e autenticados previamente.

O Django possui um módulo de autenticação extremamente completo e fácil de implementar, como veremos neste artigo.

Para a construção deste projeto, vamos iniciá-lo apenas com uma página index que exibirá uma mensagem “Página protegida”. É ela quem vamos restringir para que apenas usuários autenticados possuam acesso.

Lembrando que este projeto está neste repositório.

Cadastrando usuários

Para autenticar os usuários, primeiro precisamos cadastrá-los no banco de dados. O Django possui, em seu módulo de segurança, toda uma base para este cadastro. Para utilizá-la, vamos até o arquivo views.py da nossa aplicação e criamos o seguinte método:

def cadastrar_usuario(request):
    if request.method == "POST":
        form_usuario = UserCreationForm(request.POST)
        if form_usuario.is_valid():
            form_usuario.save()
            return redirect('index')
    else:
        form_usuario = UserCreationForm()
    return render(request, 'cadastro.html', {'form_usuario': form_usuario})

O método acima é bem simples. Basicamente, ele cria uma instância do UserCreationForm passando todos os dados da requisição (dados do usuário a ser cadastrado no BD), verifica se estes dados são válidos e os persiste no banco de dados.

Lembrando que o UserCreationForm é um Form do próprio Django utilizado para cadastrar usuários no projeto.

Para que os dados sejam cadastrados, precisamos de um template para interagir com o usuário da aplicação. Sendo assim, o arquivo cadastro.html foi criado com o seguinte conteúdo:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Cadastro de usuários</title>
</head>
<body>

<form method="post">
    {% csrf_token %}

    <div class="form-group">
        {{form_usuario.username.errors}}
        <label>Username: </label>
        {{form_usuario.username}}
    </div>

    <div class="form-group">
        {{form_usuario.password1.errors}}
        <label>Senha: </label>
        {{form_usuario.password1}}
    </div>

    <div class="form-group">
        {{form_usuario.password2.errors}}
        <label>Confirmação de senha: </label>
        {{form_usuario.password2}}
    </div>

    <div class="form-group">
        <input type="submit" value="Cadastrar" class="btn btn-primary">
    </div>
</form>

</body>
</html>

O template possui apenas um formulário com os dados que um usuário deve possuir para salvá-lo no banco de dados do projeto (username e password).

Além disso, precisamos definir uma rota para o usuário conseguir acessar o formulário. Para isso, no arquivo urls.py, definimos o seguinte conteúdo:

from django.contrib import admin
from django.urls import path, include
from .views import *

urlpatterns = [
    path('cadastrar_usuario', cadastrar_usuario, name="cadastrar_usuario"),
    path('index', index, name="index"),
]

Agora, ao acessar a rota /cadastrar_usuario, o seguinte formulário será renderizado:

Ao preencher o formulário e submetê-lo, um novo usuário será criado no banco de dados do projeto, mais especificamente na tabela auth_user:

Podemos notar que o usuário foi salvo com sucesso e que sua senha foi criptografada utilizando o sha256. Além disso, o usuário joao12 ainda não se autenticou na aplicação (o que vamos fazer no próximo tópico) e que há algumas informações em branco (first_name e email), já que estas não são obrigatórias no projeto.

Agora, precisamos utilizar estas informações no banco de dados e autenticar os usuários em nossa aplicação.

Autenticando usuários

Após cadastrar os usuários no banco de dados do projeto, vamos utilizar estas informações para autenticá-los. Para isso, o primeiro passo é criar o template (login.html) onde o próprio usuário poderá preencher com seus dados de login:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form method="post">
    {% csrf_token %}

    <div class="form-group">
        {{form_login.username.errors}}
        <label>Username: </label>
        {{form_login.username}}
    </div>

    <div class="form-group">
        {{form_login.password.errors}}
        <label>Senha: </label>
        {{form_login.password}}
    </div>

    <div class="form-group">
        <input type="submit" value="Enviar" class="btn btn-primary">
    </div>
</form>
</body>
</html>

O formulário de login é bem simples. Precisamos apenas dos campos username e password para autenticar um usuário no banco de dados. De posse dessas informações, enviamos a requisição para o método logar_usuario do arquivo views.py do projeto, que capturará estes dados e logará o usuário na aplicação (caso os dados estejam corretos):

def logar_usuario(request):
    if request.method == "POST":
        username = request.POST["username"]
        password = request.POST["password"]
        usuario = authenticate(request, username=username, password=password)
        if usuario is not None:
            login(request, usuario)
            return redirect('index')
        else:
            form_login = AuthenticationForm()
    else:
        form_login = AuthenticationForm()
    return render(request, 'login.html', {'form_login': form_login})

O método logar_usuario é bem simples. Ele irá capturar os dados enviados por meio do formulário e os utilizará para autenticar um novo usuário por meio do método authenticate do Django.

Este método irá verificar se os dados de login estão corretos (de acordo com os dados presentes no banco de dados) e salvar a resposta na variável usuario. Há dois retornos possíveis para o método authenticate: None, se os dados informados estiverem incorretos, e o usuário, caso os dados estejam corretos.

Verificamos este retorno e, caso o usuário exista no banco de dados, utilizamos o método login para logá-lo na aplicação. A partir daí, este usuário estará autenticado no projeto 🙂

Lembrando que precisamos criar a rota responsável por executar o método logar_usuario no arquivo views.py:

from django.contrib import admin
from django.urls import path, include
from .views import *

urlpatterns = [
    path('logar_usuario', logar_usuario, name="logar_usuario"),
    path('cadastrar_usuario', cadastrar_usuario, name="cadastrar_usuario"),
    path('index', index, name="index"),
]

Agora, ao acessar a rota localhost:8000/logar_usuario, o formulário de login será exibido para que possamos informar as credenciais do usuário e autenticá-lo na aplicação:

Notem que o campo last_login foi preenchido com a data e hora do último login do usuário (o id do usuário mudou porque tinha esquecido sua senha, então tive que recriá-lo 😛 )

Com isso, já estamos com os métodos de login e cadastro de usuários prontos e funcionais. O próximo passo é incrementar nosso módulo de autenticação, adicionando os métodos de logout, alterar senha e proteger páginas para que apenas usuários logados possuam acesso, mas isso nós vamos fazer nos próximos artigos desta série de autenticação com Django. Até lá 🙂

Principais comandos do Django CLI

Quando estamos iniciando os estudos com o Django, é bem comum esquecermos os principais comandos para gerenciar nossa aplicação (executar o servidor de desenvolvimento, criar um projeto, criar uma aplicação, criar migrações, etc). Pensando nisso, neste artigo veremos quais são os comandos responsáveis por cada uma das principais funcionalidades do CLI do Django.

Criar Projeto

Para criar um projeto no Django, utilizamos o seguinte comando no terminal:

django-admin startproject nome_do_projeto

Este comando irá criar um projeto Django vazio, com a estrutura de arquivos e diretórios padrão do framework.

Criar Aplicação

Após criar um projeto, precisamos criar uma (ou mais) aplicações para o projeto. Para isso, utilizamos o seguinte comando:

python manage.py startapp nome_da_app

Lembrando que este comando deverá ser executado no mesmo diretório em que se encontra o arquivo manage.py do projeto, ou seja, dentro do diretório padrão do projeto que estamos criando.

Django - Fundamentos
Curso de Django - Fundamentos
CONHEÇA O CURSO

Criar Migrações

Após determinar quais serão as entidades que utilizaremos em nosso projeto, precisamos criar as tabelas que representam estas entidades no banco de dados. Para isso, utilizamos o seguinte comando:

python mananage.py makemigrations

O comando acima irá obter a estrutura das classes definidas no arquivo models.py e criará os arquivos de migração de cada classe.

Executar Migrações

Após criar os arquivos que definem a estrutura de cada entidade no banco de dados, precisamos executar estas migrações. Para isso, utilizamos o seguinte comando:

python manage.py migrate

Com isso, todas as classes definidas no arquivo models.py serão transformadas em tabelas no banco de dados.

Executar Servidor de Desenvolvimento

Para executar o servidor de desenvolvimento do Django e, assim, testar nosso projeto, utilizamos o seguinte comando:

python manage.py runserver

Este comando irá executar o servidor do Django no endereço http://localhost:8000, que poderá ser utilizado para executar o projeto, como podemos ver na imagem abaixo:

Limpar Banco de Dados

Quando estamos desenvolvendo nossa aplicação, é comum que queiramos limpar todos os dados do banco de dados para realizar novos testes. Para realizar este procedimento, utilizamos o seguinte comando:

python manage.py flush

Este comando irá limpar todos os dados salvos no banco de dados do projeto, mantendo sua estrutura.

Abrir Shell do Banco de Dados Configurado

Se quisermos manipular o banco de dados diretamente do shell do SGBD, podemos utilizar o seguinte comando para criar uma conexão com o mesmo:

python manage.py dbshell

Este comando irá iniciar o shell do banco de dados ao qual o projeto django está configurado, como podemos ver abaixo:

Mapear BD existente para o projeto Django

Caso você possua um banco de dados já existente e queira mapeá-lo para seu projeto Django, o seguinte comando resolve esta necessidade:

python manage.py inspectdb > nome_da_app.models.py

Este comando irá mapear o banco de dados já existente no arquivo models.py da sua aplicação, conforme vimos neste artigo.