Almacenamiento de valores separados por comas en campos TextField en Django
A continuación os dejo la explicación del enfoque qué le dí a una aplicación Django para gestionar listas de valores en campos TextField.
En lugar de utilizar relaciones OneToMany, que generan tablas adicionales en la base de datos para gestionar datos relacionados, podemos optar por un enfoque más sencillo: almacenar los valores directamente en campos de tipo TextField, separados por comas. Este método es ideal cuando no necesitamos realizar consultas complejas sobre esos datos, ya que simplifica la estructura del modelo y reduce la complejidad del sistema. Además, es una técnica útil y práctica, aunque parece que existe muy poca documentación al respecto.
Modelos
En el archivo models.py, se define un campo TextField que almacenará los valores separados por comas. Por ejemplo:
class PerfilProfesional(models.Model):
softwares = models.TextField(blank=True)
sistemas_operativos = models.TextField(blank=True)
Formularios
En forms.py, puedes utilizar MultipleChoiceField con un widget de tipo CheckboxSelectMultiple para presentar los valores como checkboxes. Aquí, un ejemplo para el campo softwares:
from django import forms
SOFTWARES = [
('software1', 'Software 1'),
('software2', 'Software 2'),
# Agrega más opciones aquí
]
SIS_OPERATIVOS = [
('Windows', 'Software 1'),
('Unix', 'Unix'),
('Mac OS', 'Mac OS'),
# Agrega más opciones aquí
]
class PerfilProfesionalForm(forms.ModelForm):
softwares = forms.MultipleChoiceField(
choices=SOFTWARES,
widget=forms.CheckboxSelectMultiple(),
required=False
)
sistemas_operativos = forms.MultipleChoiceField(
choices=SIS_OPERATIVOS,
widget=forms.CheckboxSelectMultiple(),
required=False
)
class Meta:
model = PerfilProfesional
fields = ['softwares','sistemas_operativos']
# Inicialización de valores
def __init__(self, *args, **kwargs):
super(PerfilProfesionalForm, self).__init__(*args, **kwargs)
if self.instance and self.instance.pk:
self.initial['softwares'] = list(self.instance.lenguas_softwares.split(', '))
self.initial['sistemas_operativos'] = list(self.instance.sistemas_operativos.split(', '))
# Puedes inicializar los campos que quieras aquí
# Limpieza de datos
def clean_softwares(self):
return ', '.join(self.cleaned_data['softwares'])
def clean_sistemas_operativos(self):
return ', '.join(self.cleaned_data['sistemas_operativos'])
Explicación:
-
Almacenamiento en el modelo: Los campos
softwaresysistemas_operativosson camposTextFieldque contendrán los datos separados por comas. -
Múltiples opciones en el formulario: En el formulario, utilizamos
MultipleChoiceFieldpara presentar al usuario una lista de opciones con checkboxes. El atributochoicesestá vinculado a una lista de tuplas, en este casoSOFTWARESySIS_OPERATIVOS, que define las opciones disponibles. -
Inicialización de los valores: En el método
__init__del formulario, si el formulario corresponde a una instancia existente (es decir, si estamos editando un registro), se inicializan los campos de checkbox con los valores ya almacenados, dividiéndolos en una lista mediantesplit(', '). -
Limpieza de datos: El método
clean_softwaresYclean_sistemas_operativosse encargan de unir los valores seleccionados en una cadena de texto separada por comas antes de guardarlos en la base de datos.
Este enfoque es útil cuando necesitas gestionar listas simples de datos, sin necesidad de crear relaciones complejas en la base de datos, manteniendo el código más ligero y sencillo.