Usar exibições genéricas para editar dados

Concluído

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.

  1. O usuário envia uma solicitação GET para sinalizar que deseja que o formulário crie um item.
  2. O servidor envia o formulário com um token especial para impedir uma CSRF (solicitação intersite forjada).
  3. 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.
  4. O servidor valida o token de CSRF para garantir que nenhuma violação ocorra.
  5. Ele valida todas as informações para garantir que elas cumpram as regras. Uma mensagem de erro será retornada se a validação falhar.
  6. O servidor tenta salvar o item no banco de dados. Se isso falhar, uma mensagem de erro será retornada ao usuário.
  7. 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 o method 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>