Como usar Codenerix GenCreate, GenUpdate, GenDetail y GenDelete


Juanmi Taboada
Como usar Codenerix GenCreate, GenUpdate,...

 

En el último artículo describíamos Codenerix GenList para comenzar a usar los listados de CODENERIX. Ha llegado el momento de ver como crear, ver, actualizar y borrar la información de esos listados.

En este artículo hablaré sobre GenCreate, GenDetail, GenUpdate y GenDelete.

En primer lugar cabe decir que cada uno hereda de su equivalente en Django de tal modo que GenCreate hereda de CreateView, GenUpdate de UpdateView, GenDetail de DetailView y GenDelete de DeleteView.

Vamos a ver primero como serían el modelo de ejemplo que vamos a usar “Contact“:

class Contact(CodenerixModel):
    first_name = models.CharField(verbose_name=_(u'Nombre(s)'), max_length=128)
    last_name = models.CharField(verbose_name=_(u'Apellidos'), max_length=128, blank=True, null=True)
    alias = models.CharField(verbose_name=_(u'Alias'), max_length=32, blank=True, null=True)
    organization = models.CharField(verbose_name=_(u'Organización'), max_length=64, blank=True, null=True)
    borndate = models.DateField(verbose_name=_(u'Cumpleaños'), blank=True, null=True)
    address = models.TextField(verbose_name=_(u'Dirección'), blank=True, null=True)
    created_by = models.ForeignKey(User, verbose_name=_(u'Creado por'), on_delete=models.CASCADE, related_name='contacts')

    def __fields__(self, info):
        return (
            ('first_name', _(u'Nombre(s)')),
            ('last_name', _(u'Apellidos')),
            ('alias', _(u'Alias')),
            ('organization', _(u'Organization')),
        )

y su formulario “ContactForm” que heredará de GenModelForm:

from codenerix.forms import GenModelForm


class ContactForm(GenModelForm):

    class Meta:
        model = Contact
        exclude = ['created_by']

    def __groups__(self):
        return [
            (
                _(u'Principal'), 6,
                ['first_name', 6],
                ['last_name', 6],
                ['alias', 6],
            ),
            (
                _(u'Principal'), 6,
                ['organization', 6],
                ['borndate', 6],
                ['address', 6],
            )
        ]

    @staticmethod
    def __groups_details__():
        return [
            (
                _(Contact'), 12,
                ['alias', 12],
                ['organization', 12],
                ['borndate', 12],
                ['address', 12],
            )
        ]

Dado que GenModelForm es nuevo sólo voy a destacar que hereda de BaseModelForm de Django y que lo único que tiene nuevo frente a un ModelForm de Django son los grupos. Los grupos son la definición de cómo deseamos que se vea un formulario en la pantalla y se construye con una lista de tuplas que contienen:

  1. Título del bloque de campos
  2. Ancho en columnas de Bootstrap
  3. N-tuplas que se refieren a los campos del formulario donde cada tupla tendrá como primer elemento el nombre del campo que irá en esa posición y su ancho en columnas de Bootstrap. Existen más elementos en estas tuplas que explicaré en próximas publicaciones.

De este modo el formulario indicado arriba quedaría como sigue:

Donde los campos están autovalidados en el lado del navegador del usuario y por lo tanto reduce mucho en llamadas al servidor. Dicho formulario explicado con su grupo quedaría como sigue:

Descubramos los detalles de cada una de estas 4 vistas que de base funcionan como sus homólogos en Python con los mismos atributos y métodos que estos, pero ofrecen mucha más funcionalidad.

GenModify

Para poder hablar con GenCreate y GenUpdate, primero tenemos que hablar de GenModify que es el encargado de gestionar el funcionamiento cuando se crea y se actualiza un registro. No es una vista que usaremos directamente, sin embargo esta clase formará parte de forma indirecta de GenCreate y GenUpdate respectivamente. Dado que la creación y actualización de registro varía en cuestiones mínimas: el formulario coincide y las validaciones son las mismas, la clase GenModify se encarga de gestionar como actuan GenCreate y GenUpdate en cada caso precargando el formulario con el registro que se está editando en un GenUpdate y en ambos casos almacenando los cambios (nuevos o actualizados) en la base de datos.

Tabla de atributos permitidos por GenModify
Atributo Descripción
angular_delete Nombre del método de angular que recibirá la acción cuando se pulse el botón “Borrar”, por defecto “delete”.

angular_delete = "delete"

angular_submit Nombre del método de angular que recibirá la acción cuando se envíe el formulario, por defecto “submit”.

angular_submit = "submit"

buttons_bottom Muestra los botones de acción debajo del formulario, por defecto a True.

buttons_bottom = True

buttons_top Muestra los botones de acción encima del formulario, por defecto a True.

buttons_top = True

extends_base Contiene la ruta del template base del que heredará el template de List. Generalmente acude a un “base/base.html“, pero cambiando esta variable se puede indicar que cargue otro fichero diferente para ofrecer al usuario una experiencia de entorno diferente.

extends_base = "base/base.html"

form_groups Grupo a aplicar en esta vista (equivalente a __groups__), puede ser un método o una función.
form_ngcontroller Al especificar este atributo se añadirá un controlador extra al formulario que servirá para incluir funcionalidades extras accesorias al formulario estándar.

form_ngcontroller = "nuevo_controlador"

__groups__ Grupo a aplicar en esta vista (equivalente a form_groups), puede ser un método o una función.
hide_foreignkey_button Cuando este atributo está activado se muestra la opción de trabajar los campos con relaciones externas mediante ventanas modales, por defecto este este atributo está a False. En el siguiente ejemplo se pueden ver 2 campos “Marca” y “Categoría” en el cual al no existir un elemento seleccionado en “Marca” el sistema muestra un símbolo “+” para añadir un nuevo registro dado que sobre-entiende que ninguno de los que hay en la lista es válido para el usuario para rellenar dicho campo. En caso de existir un elemento seleccionado el sistema muestra un “lápiz” a fin de permitir editar el elemento seleccionado. Ambas “creación” y “edición” ocurren en una ventana modal.

En algunas ocasiones no deseamos ver estos botones dado que no queremos que el usuario acceda a dichas ventanas modales, bien porque visualmente no lo deseamos o bien porque no tiene permisos o no están desarrolladas. Al marcar este atributo como “True” se ocultarán dichos botones.

hide_foreignkey_button = False

json Devolverá una respuesta en formato JSON, por defecto True.

json = True

json_details Activará la respuesta detallada en las respuestas JSON, por defecto True.json_details = True
linkback Muestra el botón “Volver, por defecto a True.

linkback = True

linkdelete Muestra el botón “Borrar, por defecto a True. Este atributo sólo está disponible en los formularios de edición (no está habilitado para los formularios de creación dado que no hay registro que borrar).

linkdelete = True

linksavehere Muestra el botón “Guardar aquí, por defecto a True.

linksavehere = True

linksavenew Muestra el botón “Guardar y Nuevo“, por defecto a True.

linksavenew = True

show_details Al finalizar la ejecución del formulario, el sistema tratará de volver al listado, sin embargo si show_details está activada, el sistema acudirá a la vista detalles en vez de al listado.

show_details = True

show_internal_name Cuando está a True mostrará un título en el formulario. Por defecto está activado en los formularios normales y desactivado en los formularios “modales“.

show_internal_name = True

success_url_keys Un formulario correctamente completado siempre responde con un estado válido y además con un diccionario JSON que contiene al menos 2 claves:

  • __pk__ que incluye el PK del objeto creado o actualizado
  • __str__ que contiene la representación en formato texto de dicho objeto creado o actualizado.

Estas 2 claves son siempre sobreescritas por el sistema de respuesta, sin embargo si en el atributo success_url_keys se incluyen otras claves, estas también se incluirán en la respuesta del formulario podiendo ser aprovechado estos datos para conseguir información extra del objeto creado/modificado o del estado final del la operación solicitada al formulario.

El atributo success_url_keys deberá ser una lista de cadenas que pueden tener el siguiente formato:

  • “key”: será evaluado como si fuese “key:key
  • “key1:key2”: será evaluado como answer[key1]=object.key2

success_url_keys = ["id","name:title"]

title Si show_internal_name está activado se mostrará un título, el título será calculado automáticamente mediante la mezcla de la acción que puede ser “Añadiendo” o “Editando” y el nombre del formulario. Sin embargo al modificar este atributo, se mostrará directamente el contenido de este atributo evitando que sea autocalculado.

title = _("Nuevo título para el formulario")

Estos atributos están disponibles tanto en las vistas de creación como en las de edicción.

GenCreate y GenCreateModal

from codenerix.views import GenCreate, GenCreateModal

class ContactCreate(GenCreate):
    model = Contact
    form_class = ConctactForm

class ContactCreateModal(GenCreateModal, ContactCreate):
    pass

GenCreate es una vista que hereda de CreateView de Django y de GenModify. En sus mínimos necesita los mismos campos que CreateView, estos son “model” y “form_class“. Dado que GenCreate hereda de GenModify, también estarán disponibles las funcionalidades de este.

A las vistas a las que les incluyamos un GenCreateModal, conseguiremos que el render se ocupe de preparar el resultado para ser mostrado en una ventana modal. En el fondo lo que realmente ocurre es que añade la marquesita de las ventanas modales de Bootstrap y termina el renderizado en ese punto.

GenUpdate y GenUpdateModal

from codenerix.views import GenUpdate, GenUpdateModal

class ContactUpdate(GenUpdate):
    model = Contact
    form_class = ContactForm

class ContactUpdateModal(GenUpdateModal, ContactUpdate):
    pass

GenUpdate es una vista que hereda de UpdateView de Django y de GenModify. En sus mínimos necesita los mismos campos que UpdateView, estos son “model” y “form_class“. Dado que GenUpdate hereda de GenModify, también estarán disponibles las funcionalidades de este.

A las vistas a las que les incluyamos un GenUpdateModal, conseguiremos que el render se ocupe de preparar el resultado para ser mostrado en una ventana modal. En el fondo lo que realmente ocurre es que añade la marquesita de las ventanas modales de Bootstrap y termina el renderizado en ese punto.

GenDetail y GenDetailModal

from codenerix.views import GenDetail, GenDetailModal

class ContactDetail(GenDetail):
    model = Contact
    groups = ContactForm.__groups_details__()

class ContactDetailModal(GenDetailModal, ContactDetail):
    pass

GenDetail es una vista que hereda de DetailView de Django y de GenModify, usada para visualizar datos de un objeto. En sus mínimos necesita los mismos campos que DetailView, estos son “model” y “form_class“.

A las vistas a las que les incluyamos un GenDetailModal, conseguiremos que el render se ocupe de preparar el resultado para ser mostrado en una ventana modal. En el fondo lo que realmente ocurre es que añade la marquesita de las ventanas modales de Bootstrap y termina el renderizado en ese punto.

Tabla de atributos permitidos por GenDetail
Atributo Descripción
exclude_fields Es una lista de campos que serán excluídos al renderizar los datos del objeto. GenDetail mostrará siempre todos los campos del objeto, usará (al igual que los formularios) los grupos para mostrar la información organizada mediante estos y el resto de campos irán de forma consecutiva al final del grupo. Sin embargo, si un campo aparece en la lista de exclude_fields, este no será mostrado en la vista de detalles.

exclude_fields = ["contact", "price"]

extra_context Es un diccionario que contiene información extra que será enviada al template.
groups Funcionan como los grupos de las vistas de GenCreate y GenUpdate.
linkback Muestra el botón “Volver, por defecto a True.

linkback = True

linkedit Muestra el botón “Editar, por defecto a True.

linkedit = True

linkdelete Muestra el botón “Borrar, por defecto a True. Este atributo sólo está disponible en los formularios de edición (no está habilitado para los formularios de creación dado que no hay registro que borrar).

linkdelete = True

GenDelete

from codenerix.views import GenDelete

class ContactDelete(GenDelete):
    model = Contact

Es la vista encargada de borrar los registros. La razón para heredar de GenDelete se debe a que el sistema hace ciertas comprobaciones de seguridad para el borrado del registro incluyendo permisos e integridad que el propio Django no hace. Además responde adecuadamente a los controladores que atienden a la gestión de los formularios.

Hasta aquí hemos explicado todo lo necesario para operar con las vistas Genéricas de CODENERIX.

Show Comments (1)

Comments

  • Christian

    Interesante y sobretodo bien explicado, buen trabajo 🙂

Related Articles

Programación

Multiprocessing: una piscina de procesos en tu Python

Cada año durante las vacaciones, como buen informático, aprovecho para leer cosas diferentes y aprender algo nuevo, en esta ocasión he podido estudiar sobre la librería...

Posted on by Juanmi Taboada
Codenerix

¿Qué es CodenerixModel?

  En el artículo anterior hablábamos sobre CODENERIX y sus bondades. Ahora vamos a comenzar una serie de artículos que permitan profundizar en esta tecnología. Para que todo...

Posted on by Juanmi Taboada