Como usar Codenerix GenCreate, GenUpdate, GenDetail y GenDelete
🇬🇧 Read it in English, “GenCreate, GenUpdate, GenDetail and GenDelete“ En el último artículo describíamos Codenerix GenList para comenzar a usar los listados de CODENERIX. Ha...
Filter by Category
Filter by Author
🇬🇧 Read it in English, “GenCreate, GenUpdate, GenDetail and GenDelete“ En el último artículo describíamos Codenerix GenList para comenzar a usar los listados de CODENERIX. Ha...
Posted by Juanmi Taboada
🇬🇧 Read it in English, “GenList“ Anteriormente hablábamos sobre CodenerixModel para entender como se construye un modelo funcional con CODENERIX. Sin embargo, para que...
Posted by Juanmi Taboada
🇬🇧 Read it in English, “CodenerixModel“ En el artículo anterior hablábamos sobre CODENERIX y sus bondades. Ahora vamos a comenzar una serie de artículos que permitan...
Posted by Juanmi Taboada
Open South Code – 5 y 6 Mayo (La Térmica, Málaga) EVENTO GRATUITO DE SOFWARE LIBRE CREATIVIDAD, TENDENCIAS EN PROGRAMACIÓN, FUTURO Tiene lugar la 2ª edición del...
Posted by Juanmi Taboada
🇬🇧 Read it in English, “What is it CODENERIX?“ Es el nombre que recibe el software libre generado por Centrologic para desarrollo de herramientas de gestión...
Posted by Juanmi Taboada
🇬🇧 Read it in English, “GenCreate, GenUpdate, GenDetail and GenDelete“
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 [ ( _(u'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:
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.
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_submit | Nombre del método de angular que recibirá la acción cuando se envíe el formulario, por defecto “submit”.
|
buttons_bottom | Muestra los botones de acción debajo del formulario, por defecto a True.
|
buttons_top | Muestra los botones de acción encima del formulario, por defecto a 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.
|
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.
|
__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.
|
json | Devolverá una respuesta en formato JSON, por defecto 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.
|
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).
|
linksavehere | Muestra el botón “Guardar aquí“, por defecto a True.
|
linksavenew | Muestra el botón “Guardar y Nuevo“, por defecto a 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_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“.
|
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:
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:
|
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.
|
Estos atributos están disponibles tanto en las vistas de creación como en las de edicción.
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.
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.
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.
|
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.
|
linkedit | Muestra el botón “Editar“, por defecto a 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).
|
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.
During our operations, very often, we use a Waterlinked Underwater GPS. This helps us to keep track in 3D of our movements and link video recording’s timing and telemetry to...
In my last post, “How I designed the frame for my Underwater ROV“, I gave all details about the design I used for the frame for Alioli Underwater ROV. In this post, I...
Interesante y sobretodo bien explicado, buen trabajo 🙂