Remove the “choices” part in the category field. By having it “choices=[(”, ”), ]”, you are requiring the choice to be blank. Any value would fail. If you remove, like below, any value will be accepted (assuming it’s under 20 characters).
category = models.CharField(max_length=20)
I have a Model and a ModelForm. The ModelForm has a dependent dropdown list implemented with JQuery. The category dropdown changes accordingly each time a choice from the gender dropdown is selected (Done with JQuery). Whenever I try to save the ModelForm in my views, I get an error saying that the choice that I have selected is not valid. Does it have to do with the choices/options to the category dropdown being added after a choice from the gender dropdown has been selected? Does it cause some conflict with the default empty two-tuple of the category field? The errors occur on the category field.
In models.py,
GENDER_CHOICES = [
('Male', 'Male'),
('Female', 'Female'),
]
class Person(models.Model):
name = models.CharField(max_length=50, unique=True)
gender = models.CharField(max_length=7, choices=GENDER_CHOICES)
category = models.CharField(max_length=20, choices=[('', ''), ])
In forms.py,
class PersonForm(ModelForm):
class Meta:
model = Person
fields = [
'name',
'gender',
'category',
]
In views.py,
def personform_page(request):
context = {}
if request.method == 'POST':
personform = PersonForm(request.POST)
if personform.is_valid():
personform.save()
return redirect('personform_page')
context['personform'] = personform
else:
personform = PersonForm()
context['personform'] = personform
context['male_categories'] = MALE_CATEGORIES
context['female_categories'] = FEMALE_CATEGORIES
return render(request, 'app1/personform_page.html', context=context)
In app1/personform_page.html,
<form class="form-class" action="" method="post" enctype="multipart/form-data">
{% csrf_token %}
{% for field in personform %}
<p>
{{ field.label_tag }}
{{ field }}
{% if field.help_text %}
<small style="color: black;"> {{ field.help_text }} </small>
{% endif %}
{% for error in field.errors %}
<p style="color: red;"> {{ error }} </p>
{% endfor %}
</p>
{% endfor %}
<button class="btn btn-outline-primary" type="submit">Join</button>
</form>
<script>
$(document).ready( function() {
$("#id_category").hide();
$("#id_gender").on('change', function(){
var gender = $("#id_gender").val();
if(gender == 'Male'){
$('#id_category').empty();
$("#id_category").show();
var maleCategories = ['Male Category 1', 'Male Category 2', 'Male Category 3'];
var length = maleCategories.length;
var i;
for(i=0; i < length; i++){
maleCategory = maleCategories[i];
$('#id_category').append(
`
<option value="${maleCategory}">
${maleCategory}
</option>
`
);
}
}
else if(gender == 'Female'){
$('#id_category').empty();
$("#id_category").show();
var femaleCategories = ['Female Category 1', 'Female Category 2', 'Female Category 3'];
var length = femaleCategories.length;
var i;
for(i=0; i < length; i++){
femaleCategory = femaleCategories[i];
$('#id_category').append(
`
<option value="${femaleCategory}">
${femaleCategory}
</option>
`
);
}
}
else{
$('#id_category').empty();
}
});
});
</script>
I realized that entering choices other than the ones originally assigned would violate the integrity. So, I populated the choice attribute with all the choices in the beginning and then used JQuery to display the appropriate ones based on the choice selection of the gender field.