Django

Compartilhando rotas entre apps no Django

Um projeto Django é composto por uma ou mais aplicações, que possui um arquivo de rotas. Agora imagine que tenhamos duas apps com rotas de mesmo nome ou que precisamos executar métodos de uma outra app … Como diferenciar cada rota dentro do projeto e como compartilhar as rotas entre as aplicações de um projeto? É o que veremos neste artigo.

Utilizando namespaces no Django

A compartilhação de rotas entre apps no Django é muito simples. A primeira coisa a se fazer é determinar o namespace daquele arquivo de rotas. Este namespace é o que define de onde a rota pertence (a qual app aquela rota foi criada).

Imagine que você tenha um projeto com duas (ou mais) aplicações e que há rotas nessas aplicações que são compartilhadas entre as apps. Para realizar este “compartilhamento”, precisamos definir o nome do namespace de cada arquivo de rotas. É este nome que identificará de onde a rota será chamada.

Para isso, no arquivo urls.py da app que queremos compartilhar as rotas, definimos a seguinte configuração no app_name:

from django.urls import path
from .views import *

app_name = 'admin_blog'

urlpatterns = [
    path('listar_posts/', listar_posts, name='listar_posts'),
    path('editar_post/<int:id>', editar_post, name='editar_post'),
    path('remover_post/<int:id>', remover_post, name='remover_post'),
    path('cadastrar_post/', cadastrar_post, name='cadastrar_post'),

]

É o conteúdo do app_name que determina como chamaremos as rotas externamente.

Django - Desenvolvimento de APIs REST
Curso de Django - Desenvolvimento de APIs REST
CONHEÇA O CURSO

Além disso, precisamos determinar que o conjunto de rotas da app possui o namespace ‘admin_blog’ no arquivo de rotas do projeto:

urlpatterns = [
    path('admin_blog/', include('admin_blog.urls', namespace='admin_blog')),
  #...
]

Invocando rotas em outras apps com Django

Agora que determinamos a configuração do app_name no arquivo de rotas da aplicação, podemos executá-las externamente. Para isso, a nomenclatura é a seguinte:

nome_definido_no_app_name:nome_da_rota

Sendo assim, se quisermos executar a rota ‘listar_posts’, por exemplo, a partir de um template localizado em outra app, definimos a tag url da seguinte forma:

<li class="nav-item">
    <a class="nav-link" href="{% url 'admin_blog:listar_posts' %}">Admin</a>
</li>

Com isso, a rota a ser executada será do método listar_posts que está definido na outra app do projeto.

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

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.

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.

Utilizando o Redis como Cache em um projeto Django

A performance de um projeto é de vital importância para o sucesso de uma aplicação. Dificilmente um site que demore um tempo considerável para responder uma solicitação de um usuário, não sucumbirá ao fracasso. Pensando nisso, há diversas maneiras de tentar melhorar o desempenho de uma aplicação, dentre elas, utilizar o Cache para armazenar dados que são frequentemente utilizados, é uma ótima alternativa.

Como funciona o Cache

O Cache é um recurso que possibilita o acesso às informações de forma mais rápida. Basicamente, é uma forma de armazenar determinadas informações que são consumidas com mais frequência para que elas sejam disponibilizadas no menor tempo possível.

O funcionamento do Cache pode ser entendido da seguinte forma:

  1. A aplicação verifica se os dados solicitados estão em cache;

  2. Se sim, o cache devolve para a aplicação, que os exibe;

  3. Se não, os dados são obtidos do banco de dados, salvos no cache e retornados para aplicação;

  4. Da próxima vez, o cache já possuirá os dados armazenados e, assim, retornados em um tempo menor.

Instalando o Redis

A instalação do Redis varia conforme o sistema operacional utilizado, abaixo veremos como instalar o Redis no Windows, Linux e macOS.

Windows

A instalação do Redis no Windows é bem simples. Primeiro, precisamos baixar o arquivo .zip do diretório oficial do Redis ():

Após realizar o download, descompactamos e executamos o arquivo redis-server, localizado no diretório 32bits ou 64bits, dependendo do sistema operacional.

Linux

A instalação do Redis no Linux também é bem simples. Primeiro, abrimos o terminal e digitamos os seguintes comandos:

sudo apt-get install redis-server
sudo systemctl enable redis-server.service

Com isso, o Redis será instalado e executado no Linux.

macOS

Para instalar o Redis no macOS também é super simples. Com o Homebrew instalado, podemos abrir o terminal e digitar o seguinte comando:

brew install redis
ln -sfv /usr/local/opt/redis/*.plist ~/Library/LaunchAgents

Com isso, o Redis será instalado e configurado para iniciar sempre que ligarmos o computador.

Configurando o Redis no Django

Com o Redis instalado, precisamos configurar a comunicação entre as tecnologias (Django e Redis). Para isso, o primeiro passo é instalar o pacote django-redis na virtualenv do projeto seguindo os seguintes passos:

No PyCharm, vamos até a aba “Project Interpreter” e clicamos no “+” localizado no canto inferior esquerdo:

Após isso, buscamos pelo pacote “django-redis” e o instalamos em nossa virtualenv:


Com isso, o Redis já está pronto para ser utilizado em nosso projeto Django 🙂

Utilizando o Redis como Cache

Após instalar e configurar o Redis em nosso projeto Django, precisamos configurar o projeto para utilizar o Redis como Cache das informações. Para isso, no arquivo settings.py, adicionamos a seguinte configuração:

CACHES = {
    'default': {
        'BACKEND': 'django_redis.cache.RedisCache',
        'LOCATION': 'redis://127.0.0.1:6379/1',
        'OPTIONS': {
            'CLIENT_CLASS': 'django_redis.client.DefaultClient'
        },
        'KEY_PREFIX': 'django_orm'
    }
}

A configuração acima permitirá que o Django se comunique com o servidor do Redis que está sendo executado localmente.

Agora precisamos indicar quais páginas utilizarão o Cache para armazenar suas informações. Para isso, no nosso arquivo de views do projeto, adicionamos a anotação @cache_page(tempo_de_vida_cache) nos métodos que queremos utilizar o cache (normalmente, nas páginas com mais acessos):

@cache_page(60)
def listar_clientes(request):
    clientes = cliente_service.listar_clientes()
    return render(request, 'clientes/lista_clientes.html', {'clientes': clientes})

Com isso, sempre que um usuário solicitar o método para listagem de todos os clientes, o Django, primeiro, verificará se estas informações existem no Redis. Se sim, é de lá que as informações serão listadas, caso contrário, o Django fará uma consulta no banco de dados, obterá a lista de clientes, inserirá no cache e retornará ao usuário.

Comparando performances

A quantidade de requisições por segundo pode variar um pouco, mas é bem nítido o ganho de performance do uso do Redis como Cache em nossa aplicação. Na imagem abaixo podemos ver a diferença entre a quantidade de requisições utilizando o Redis e o uso do banco de dados:

Conclusão

O uso do Cache é uma ótima alternativa quando precisamos garantir o retorno dos dados em um tempo menor em páginas que são frequentemente acessadas. Vale lembrar que não devemos (e nem precisamos) usá-lo em todas as páginas, apenas nas mais acessadas.