Django: Select a valid choice. [..] is not one of the available choices using TextChoices

as per the title says, here’s my error upon the process of validation of a form.

Select a valid choice. 1 is not one of the available choices.

Here’s the different pieces of code I have.

class Cat(models.Model):
    class Sex(models.TextChoices):
        M = 1, 'Male'
        F = 2, 'Female'
     sex = models.PositiveSmallIntegerField(choices=Sex.choices, blank=False, null=False)

class CatForm(forms.ModelForm):
    # Other fields that I think are useless in this error but maybe I'm missing something for the TextChoice of sex to work out here?
    fur_color = forms.ModelMultipleChoiceField(queryset=FurColor.objects.get_all(), required=False, widget=forms.CheckboxSelectMultiple)
    birth_date = forms.DateField(widget = forms.SelectDateWidget(years=range(1980, 2023)))
    class Meta:
        model = Cat
        exclude = ('user','registered_on')

def register_cat(request):
    context = {}
    if request.method == 'POST':
        context['form'] = CatForm(data=request.POST)
        if context['form'].is_valid():
            cat = context['form'].save(commit=false)
            cat.user = request.user
            return redirect('meet')
        context['form'] = CatForm()
    return render(request, 'register_cat.html', context)

The sex field in the form appear as a select list, but when I select either of Male or Female, it doesn’t seems to be able to make the link back in the model.

Do I need do modify my to make it work. Or my model is flawed to begin with ?
I have Django 4.2.5.

Thanks in advance.

>Solution :

This is likely because you use TextChoices subclass, you probably should use an IntegerChoices object:

class Cat(models.Model):
    class Sex(models.IntegerChoices):
        M = 1, 'Male'
        F = 2, 'Female'

    sex = models.PositiveSmallIntegerField(
        choices=Sex.choices, blank=False, null=False

The choices will have as difference that the choices for a TextChoices are '1' and '2', so strings, whereas for IntegerChoices, these are 1 and 2, so integers.

Leave a Reply