Estoy tratando de mostrar un formulario (con casilla de verificación de selección múltiple) y guardar los datos en la base de datos. Pero teniendo algún problema.
Aquí está mi modelo:
class Preference(models.Model): CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')] BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')] SUBJECT_CHOICES = [('H', 'HINDI'), ('M', 'MATH'), ('E', 'ENGLISH')] class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False) board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False) subject = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default='M', blank=False)mi formulario:
class PreferenceForm(forms.ModelForm): class Meta: model = Preference fields = ['class', 'board', 'subject'] widgets = { 'board': forms.RadioSelect(), 'subject': forms.CheckboxSelectMultiple() }Mi vista:
def pref(request): form = PreferenceForm(request.POST or None) if form.is_valid(): form.save() return render(request, 'website/thanks.html') else: print(form.errors) return render(request, 'website/pref.html', {'form': form})Muestra el formulario con la casilla de verificación, pero no puedo guardar esos datos en la base de datos incluso cuando selecciono una sola opción.
Error mostrado: - `
<li>Subject<ul class="errorlist"><li>Select a valid choice. ['H', 'M'] is not one of the available choices.</li></ul></li>Toda ayuda/sugerencias son apreciadas, gracias.
En primer lugar, cambie el nombre del campo class dentro de su modelo a otra cosa. class es una palabra reservada de Python y podría causarle problemas más adelante.
En segundo lugar, para representar un CharField como un widget CheckboxSelectMultiple , la declaración de campos de su modelo debe cambiar. Ahora, le está diciendo al campo de subject que acepte un solo valor (entre los valores 'H' , 'M' y 'E' ), pero, a través de su formulario, intenta darle valores múltiples ( ['H', 'M'] , que significa 'H' y 'M' ). Esa es la causa de tu error. Está esperando un valor mientras le das más de uno.
La solución a su problema es crear otro modelo, diga Subject y dentro de ese modelo declare SUBJECT_CHOICES y un solo campo (digamos name ). Luego, en su modelo de Preference , cambie el campo de subject a ManyToManyField , en lugar de CharField . De esa forma, el campo de subject del modelo de Preference podrá aceptar más de un valor.
Algo como esto:
class Subject(models.Model): HINDI = 'H' MATH = 'M' ENGLISH = 'E' SUBJECT_CHOICES = [ (HINDI, 'HINDI'), (MATH, 'MATH'), (ENGLISH, 'ENGLISH') ] name = models.CharField(max_length=2, choices=SUBJECT_CHOICES, default=MATH) def __str__(self): return self.name class Preference(models.Model): CLASS_CHOICES = [('1', '1'), ('2', '2'), ('3', '3')] BOARD_CHOICES = [('C', 'CBSE'), ('I', 'ICSE'), ('S', 'State Board')] # RENAME THE class FIELD PLEASE, ie class_number! class = models.CharField(max_length=2, choices=CLASS_CHOICES, default='1', blank=False) board = models.CharField(max_length=2, choices=BOARD_CHOICES, default='C', blank=False) # Notice the plural name of the field. Subjects, not subject, since we're expecting more than one value into this field. subjects = models.ManyToManyField(Subject)Por fin:
No olvide crear los objetos Subject (a través del administrador o el ./manage shell ). Si usa el administrador, es bastante simple. Si usa el shell , haga lo siguiente:
from myapp.models import Subject [Subject.objects.create(name=choice[0]) for choice in Subject.SUBJECT_CHOICES] Actualice el archivo forms.py con los nuevos subjects de nombre de campo.