I got a model in my app that use an ArrayField (‘caracteristicas’) where its base model its a CharField with choices from a different TextChoices class. When I try to save the generated object, its launch an error with no “exception message” in the Django webpage. If I try to do it in the DjangoAdmin Its comes to a stack overflow of recursion.
There is no problem in the form that I use to create the object nor the method (‘Exception as e’ and ‘form_class.errors’ are both empty)
I tried to create an object of “Espacio” without this ArrayField (simply various boolean fields with True if it got the characteristic and False in the other case)…and it works! I dont know whats happening
Code below
Model “Espacio”
from django.db import models
from django.contrib.postgres.fields import ArrayField
from usuarios.models import User
from base.models import EstadoEspacio, Caracteristicas, TiposEspacios
Create your models here.
Modelo asociado a los espacios
class Espacio(models.Model):
# Título del espacio
titulo = models.CharField(max_length=100)
# Descripción del espacio
descripcion = models.TextField()
# Imágenes del espacio
image1 = models.ImageField(upload_to='base/Images/EspaciosImages')
image2 = models.ImageField(upload_to='base/Images/EspaciosImages')
image3 = models.ImageField(upload_to='base/Images/EspaciosImages')
# Tipo de combo
opcionesTiposEspacio = [(choice.value, choice.label) for choice in TiposEspacios]
tipoEspacio = models.CharField(choices=opcionesTiposEspacio, max_length= 2, default=TiposEspacios.otros)
# Superficie del espacio
superficie = models.IntegerField()
def caracteristicaDefault():
return Caracteristicas.baño
# Características del espacio
#opcionesCaracteristicas = [(choice.value, choice.label) for choice in Caracteristicas]
caracteristicas = ArrayField(base_field=models.CharField(max_length=100))
# Dirección del espacio
direccion = models.CharField(max_length=150)
# Fecha de creación del espacio
created = models.DateTimeField(auto_now_add = True)
opcionesEstados = [(choice.value, choice.label) for choice in EstadoEspacio]
estado = models.CharField(max_length=2, choices=opcionesEstados, default=EstadoEspacio.publicado)
# Relación con el usuario propietario del espacio
user = models.ForeignKey(User, on_delete=models.CASCADE)
def __str__(self):
return self.titulo
View “nuevoEspacio”
def nuevoEspacio(request):
opcionesCaracteristicas = [(choice.value, choice.label) for choice in Caracteristicas]
if request.method == ‘POST’:
print(request.POST)
# Crear una instancia del formulario con los datos de la solicitud
form_class = espacioForm(request.POST, request.FILES)
if form_class.is_valid():
try:
# Guardar el espacio en la base de datos, asociándolo al usuario actual
espacio = form_class.save(commit=False)
espacio.user = request.user
caracteristicasSeleccionadas = []
for i,j in enumerate(opcionesCaracteristicas):
field_name = f"caracteristicas_{i}"
if request.POST.get(field_name):
caracteristicasSeleccionadas.append(request.POST.get(field_name))
espacio.caracteristicas = ", ".join(caracteristicasSeleccionadas)
print(form_class.errors)
espacio.save()
# Mostrar mensaje de éxito y redirigir a la página principal
messages.success(request, 'Espacio creado correctamente', 'success')
return redirect('/')
except Exception as e:
messages.error(request, f'No se pudo crear el espacio:{str(e)}', 'danger')
return redirect('nuevoEspacio')
else:
# Crear una instancia vacía del formulario
form_class = espacioForm()
contexto ={
'form': form_class,
'caracteristicas': opcionesCaracteristicas,
}
messages.error(request, form_class.errors, 'danger')
Form “espacioForm”
class espacioForm(forms.ModelForm):
opcionesCaracteristicas = forms.MultipleChoiceField(choices=[(choice.value, choice.label) for choice in Caracteristicas], widget= forms.CheckboxSelectMultiple(attrs={‘class’: ‘custom-control-input’}), required=False)
caracteristicas = forms.CharField(widget=forms.HiddenInput(), required=False)
class Meta:
model = Espacio
# Campos excluidos del formulario
exclude = ('user', 'estado')
# Todos los campos del modelo se incluyen en el formulario
fields = "__all__"
# Configuración de widgets para los campos del formulario
widgets = {
'titulo': forms.TextInput(attrs={'class': 'form-control', }),
'descripcion': forms.Textarea(attrs={'class': 'form-control', 'style':'height: 100px'}),
'image1': forms.FileInput(attrs={'class': 'form-control form-control-sm my-3', 'type':'file'}),
'image2': forms.FileInput(attrs={'class': 'form-control form-control-sm my-3', 'type':'file'}),
'image3': forms.FileInput(attrs={'class': 'form-control form-control-sm my-3', 'type':'file'}),
'tipoEspacio': forms.Select(attrs={'class': 'custom-select'}),
'superficie' : forms.NumberInput(attrs={'class': 'form-control'}),
'direccion': forms.TextInput(attrs={'class': 'form-control', }),
}
Template (only the fragment where I capture the characteristic
I was manually debugging the view and discover that the problem its in the line “espacio.save()”, all the other lines works properly
If someone can bend me a hand, I will be eternally grateful