Usar exibições genéricas para editar dados
Assim como ocorre com o código necessário para exibir os dados, o código para permitir que os usuários modifiquem os dados é repetitivo. Ele também pode ser entediante, pois várias etapas são necessárias para garantir que os dados sejam válidos e enviados corretamente. A boa notícia é que o sistema de exibição genérica pode simplificar a quantidade de código que precisamos para habilitar essa funcionalidade.
Criar itens
Antes de explorarmos como o Django pode simplificar o desenvolvimento, devemos examinar o processo que permite aos usuários modificar os dados. Vamos explorar o fluxo de trabalho usado pelo servidor para gerenciar o processo de criação de um item ou dado e o trabalho que é necessário para a criação do formulário HTML.
Fluxo de trabalho de criação
Superficialmente, o código necessário para permitir que um usuário crie um item pode parecer trivial. Acontece que se trata, na verdade, de um processo enganosamente envolvido.
- O usuário envia uma solicitação GET para sinalizar que deseja que o formulário crie um item.
- O servidor envia o formulário com um token especial para impedir uma CSRF (solicitação intersite forjada).
- O usuário preenche o formulário e seleciona Enviar, o que envia uma solicitação POST para indicar que o formulário foi preenchido.
- O servidor valida o token de CSRF para garantir que nenhuma violação ocorra.
- Ele valida todas as informações para garantir que elas cumpram as regras. Uma mensagem de erro será retornada se a validação falhar.
- O servidor tenta salvar o item no banco de dados. Se isso falhar, uma mensagem de erro será retornada ao usuário.
- Depois de salvar o novo item com êxito, o servidor redireciona o usuário para uma página de êxito.
Esse processo exige bastante código. A maior parte dele é clichê, o que significa que é o mesmo sempre que você o cria.
Formulários
Criar um formulário HTML pode ser um processo entediante. Os desenvolvedores frequentemente copiam e colam marcas input
, executando loops em listas para criar listas suspensas e configurando botões de opção. Sempre que o modelo for alterado, o formulário precisará ser atualizado.
Talvez você tenha observado que os modelos que criamos no Django contêm tudo o que é necessário para criar o formulário. Quando adicionamos os vários campos, indicamos os tipos de dados, que são acoplados a diferentes elementos HTML. Por exemplo, um campo booliano será uma caixa de seleção, e uma chave estrangeira normalmente será uma lista suspensa.
Exibições genéricas para modificar dados
Uma das principais metas do Django é eliminar a necessidade de recriar constantemente os mesmos blocos de código. A fim de apoiar essa meta para modificações de dados, o Django fornece uma coleção de classes e formulários genéricos para gerenciar essa carga de trabalho para nós. Como veremos, ele inclui todo o código necessário e pode, até mesmo, criar o formulário de maneira dinâmica. As classes usadas para criar, atualizar e excluir dados são chamadas CreateView
, UpdateView
e DeleteView
.
CreateView
A classe CreateView
é usada para permitir que um usuário crie itens. Ela percorre o processo anterior e cria o formulário dinamicamente. Após o êxito, ela exibe a página de detalhes do item recém-criado.
Você especifica o model
e o template_name
que deseja associar a ela, exatamente como faria com as outras exibições genéricas. A principal diferença para CreateView
é a inclusão de uma propriedade fields
na qual você lista os campos editáveis. Usando essa propriedade, você pode garantir que os campos que não precisem ser editados, como uma data de criação, não sejam exibidos no formulário. A exibição usada para criar um cão pode ser semelhante ao seguinte exemplo:
from . import models
from django.views import generic
class DogCreateView(generic.CreateView):
model = models.Dog
template_name = 'dog_form.html'
fields = ['name', 'description', 'shelter']
UpdateView
A classe UpdateView
se comporta de maneira idêntica a CreateView
. A única diferença é que ela carrega automaticamente um item com base no parâmetro pk
. O Django usa essa convenção para a chave primária de um item.
from . import models
from django.views import generic
class DogUpdateView(generic.CreateView):
model = models.Dog
template_name = 'dog_form.html'
fields = ['name', 'description', 'shelter']
Após a criação ou a atualização de um item com êxito, o Django redireciona o usuário para a página de detalhes do item. Ele recupera a URL para os detalhes usando get_absolute_url
no modelo associado. Você implementa esse método retornando a URL correta. Recupere a URL apropriada de URLconf usando reverse
. Observe que kwargs
é usado para transmitir a pk
ou o parâmetro de chave primária para a rota.
from django.db import models
# TODO: Import reverse
from django.urls import reverse
class Dog(models.Model):
# Existing code
def get_absolute_url(self):
return reverse('dog_detail', kwargs={"pk": self.pk})
DeleteView
A classe DeleteView
é semelhante a UpdateView
. Ela permite que um usuário exclua um item e identifique o item a ser excluído usando pk
. Ao contrário de UpdateView
, fields
não é necessário porque você excluirá o item inteiro. Além disso, como nenhum item foi criado nem atualizado recentemente, precisamos determinar a localização para a qual desejamos redirecionar o usuário. Podemos criar um redirecionamento definindo a success_url
com o valor apropriado. Você pode pesquisar uma URL usando reverse_lazy
.
from . import models
from django.views import generic
from django.urls import reverse_lazy
class AuthorDelete(DeleteView):
model = Author
success_url = reverse_lazy('author-list')
Observação
Usamos reverse_lazy
por causa da ordem em que as informações são carregadas no Django.
Modelos de formulário para criação e atualização
As exibições genéricas podem criar o formulário HTML dinamicamente. Basta fornecer um modelo para servir como o espaço reservado para o formulário. O modelo de espaço reservado garante que o formulário corresponda ao restante do site. Felizmente, não precisamos de muito código para criá-lo.
As exibições genéricas criam automaticamente uma variável form
para o modelo a ser usado. Os elementos de formulário fornecidos pelo Django podem ser exibidos dentro de marcas <p>
ou como uma <table>
.
A variável form
contém todo o HTML apropriado para criar os controles com base no formulário. Ela não contém a própria marca <form>
nem um botão Enviar. O modelo precisa incluir quatro itens:
- O elemento
form
com omethod
definido como POST, porque essa configuração dispara a operação de salvamento no servidor. - O código
{% csrf_token %}
para adicionar o token de CSRF para impedir a falsificação. - O código
{{ form.as_p }}
ou{{ form.as_table }}
para exibir o formulário gerado dinamicamente. - O botão
submit
.
O código a seguir pode funcionar como o host para qualquer formulário de exibição genérica.
<form method="post">{% csrf_token %}
{{ form.as_p }}
<button type="submit">Save</button>
</form>