Uso de vistas genéricas para editar datos

Completado

Al igual que ocurre con el código necesario para mostrar los datos, el código para permitir que los usuarios modifiquen los datos es repetitivo. También puede resultar tedioso, ya que se requieren varios pasos para asegurarse de que los datos son válidos y se envían correctamente. Afortunadamente, el sistema de vistas genéricas puede simplificar la cantidad de código que necesitamos para habilitar esta función.

Creación de nuevos elementos

Antes de explorar la forma en la que Django puede optimizar nuestro desarrollo, deberíamos revisar el proceso que permite a los usuarios modificar datos. Vamos a explorar el flujo de trabajo que utiliza el servidor para administrar el proceso de creación de un nuevo elemento o fragmento de datos, y el trabajo que va a crear el formulario HTML.

Flujo de trabajo de creación

A primera vista, el código para permitir que un usuario cree un elemento podría parecer trivial. Pero, por lo visto, se trata de un proceso aparentemente complicado.

  1. El usuario envía una solicitud GET para indicar que quiere que el formulario cree un elemento.
  2. El servidor envía el formulario con un token especial para evitar la falsificación de solicitud entre sitios (CSRF).
  3. El usuario completa el formulario y selecciona Enviar, que envía una solicitud POST para indicar que el formulario se ha completado.
  4. El servidor valida el token CSRF para asegurarse de que no se ha producido ninguna alteración.
  5. El servidor valida toda la información para asegurarse de que cumple las reglas. En caso de que se produzca un error de validación, se devolverá un mensaje de error.
  6. El servidor intenta guardar el elemento en la base de datos. Si se produce un error, se devuelve al usuario un mensaje de error.
  7. Después de guardar correctamente el elemento nuevo, el servidor redirige al usuario a una página de éxito.

¡Este proceso requiere bastante código! La mayor parte de este es reutilizable, lo que significa que es el mismo cada vez que se crea.

Formularios

La creación de un formulario HTML puede ser un proceso tedioso. Los desarrolladores a menudo copian y pegan etiquetas input, recorren listas para crear listas desplegables y configuran botones de radio. Cada vez que el modelo cambia, debe actualizarse el formulario.

Es posible que haya observado que los modelos que creamos en Django contienen todo lo necesario para crear el formulario. Cuando agregamos los distintos campos, indicamos los tipos de datos, que se acoplan con distintos elementos HTML. Por ejemplo, un campo booleano sería una casilla y una clave externa normalmente sería una lista desplegable.

Vistas genéricas para modificar datos

Uno de los objetivos clave de Django es eliminar la necesidad de volver a crear constantemente los mismos bloques de código una y otra vez. Para que este objetivo sea compatible con las modificaciones de datos, Django proporciona una recopilación de clases y formularios genéricos con el fin de administrar esta carga de trabajo. Como veremos, incluye todo el código necesario y puede incluso crear el formulario por nosotros dinámicamente. Las clases utilizadas para crear, actualizar y eliminar datos se denominan CreateView, UpdateView y DeleteView respectivamente.

CreateView

La clase CreateView se utiliza para permitir a los usuarios crear elementos. Le guía por el proceso anterior y crea dinámicamente el formulario. Una vez que se ha realizado correctamente, muestra la página de detalles del elemento recientemente creado.

Se debe especificar el elemento model y template_name que quiere asociar, tal como se haría con las otras vistas genéricas. La diferencia clave de CreateView es la inclusión de una propiedad fields en la que se muestra una lista de los campos modificables. Con esta propiedad, puede asegurarse de que los campos que no se deben editar, como una fecha de creación, no aparecen en el formulario. La vista para crear un perro podría ser similar a la del ejemplo siguiente:

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

La clase UpdateView se comporta de manera idéntica a CreateView. La única diferencia es que carga automáticamente un elemento basado en el parámetro pk. Django usa esta convención para la clave principal de un elemento.

from . import models
from django.views import generic

class DogUpdateView(generic.CreateView):
    model = models.Dog
    template_name = 'dog_form.html'
    fields = ['name', 'description', 'shelter']

Después de crear o actualizar correctamente un elemento, Django redirige a la página de detalles del elemento. Recupera la dirección URL de los detalles mediante el uso de get_absolute_url en el modelo asociado. Para implementar este método, devuelva la dirección URL correcta. Puede recuperar la dirección URL apropiada de URLconf mediante reverse. Tenga en cuenta que kwargs se usa para pasar pk o el parámetro de clave principal o a la ruta.

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

La clase DeleteView es parecida a UpdateView. Permite a un usuario eliminar un elemento e identifica el elemento que se va a eliminar mediante pk. A diferencia de UpdateView, fields no se necesita porque se eliminará todo el elemento. Además, dado que no se ha creado ni actualizado ningún elemento recientemente, necesitamos determinar dónde queremos redirigir al usuario. Podemos crear un redireccionamiento estableciendo success_url en el valor adecuado. Puede buscar una dirección URL mediante 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')

Nota:

Usamos reverse_lazy debido al orden en que se carga la información en Django.

Plantillas de formulario para crear y actualizar

Las vistas genéricas pueden crear el formulario HTML por nosotros dinámicamente. Todo lo que debemos proporcionar es una plantilla que actúe como el marcador de posición del formulario. La plantilla de marcador de posición garantiza que el formulario coincida con el resto de nuestro sitio. Afortunadamente, no necesitamos mucho código para crearla.

Las vistas genéricas crean automáticamente una variable form para que la use nuestra plantilla. Los elementos del formulario que proporciona Django se pueden mostrar dentro de las etiquetas <p> o como un elemento <table>.

La variable form contiene todo el HTML adecuado para crear los controles del formulario. No contiene la propia etiqueta <form> o un botón de envío. Nuestra plantilla debe incluir cuatro elementos:

  • El elemento form con method establecido en POST, porque esta configuración desencadena la operación de almacenamiento en el servidor.
  • El código {% csrf_token %} para agregar el token CSRF a fin de evitar la suplantación de identidad.
  • El código {{ form.as_p }} o {{ form.as_table }} para mostrar el formulario generado de forma dinámica.
  • El botón submit.

El código siguiente puede actuar como el host para cualquier formulario de vista genérica.

<form method="post">{% csrf_token %}
    {{ form.as_p }}
    <button type="submit">Save</button>
</form>