I'm new to Django and any help is appreciated, How can I restrict the choice option in one field based on a previous field. For example, if I select 'dog' for animal, I want to remove 'chocolate' from the FOOD_CHOICE. Thank you!!!
ANIMAL_CHOICE = (
('a','cat'),
('b','dog'),
('c','fish'),
)
FOOD_CHOICE = (
('a', 'chocolate'),
('b', 'kittySnack'),
('c', 'steak'),
)
class Animal(models.Model):
animal = models.CharField(max_length=1, choices= ANIMAL_CHOICE)
food = models.CharField(max_length=1, choices= FOOD_CHOICE)
As explained here, you should do the validation on the model form or in the model clean method and raise a ValidationError
there.
Here is an example, in which you could override the clean
method of your model's form:
forms.py
class AnimalForm(ModelForm):
class Meta:
model = Animal
fields = "__all__"
def clean(self):
cleaned_data = super(AnimalForm, self).clean()
animal = self.cleaned_data.get("animal")
food = self.cleaned_data.get("food")
if animal == "b" and food == "a": # Might not work, but this is the general idea
raise forms.ValidationError("Chocolate can't be selected with Dogs")
N.B.: At the line where I commented that it might not work, you'll have to debug a bit. I don't remember (and I can't test right now) if the cleaned_data
returns a tuple or the actual value, or the humand-readable value.
Now, I guess that you want your select in your HTML to dynamically change. For the frontend, you'll need to do a bit of JavaScript. There are many ways on how to do it with JS, but here is one:
(in your template, between <script>
tags)
var selectAnimal = document.getElementById("select-animal");
var selectFood = document.getElementById("select-food");
selectAnimal.addEventListener("change", function() {
if(this.value == "a")
{
// remove from select the "chocolate" option
for (var i=0; i<selectFood.length; i++) {
if (selectFood.options[i].text == 'chocolate')
selectFood.remove(i);
}
}
else {
// checking if "chocolate" is in select or not
let has_chocolate = false;
for (var i=0; i<selectFood.options.length; i++){
if (selectFood.options[i].text == "chocolate"){
has_chocolate = true;
}
}
if (!has_chocolate){ // if "chocolate" is missing
option = document.createElement("option");
option.text = "chocolate";
option.value = "a";
selectFood.add(option);
}
}
});