В Django удаление опций в выпадающем поле выбора на основе значения, выбранного в другом поле в модели

Я новичок в Django и любая помощь будет оценена по достоинству, Как я могу ограничить возможность выбора в одном поле на основе предыдущего поля. Например, если я выбираю "собака" для животного, я хочу удалить "шоколад" из FOOD_CHOICE. Спасибо!!!

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)

Как объяснено здесь, вы должны выполнять валидацию на форме модели или в методе очистки модели и поднимать ValidationError там.

Вот пример, в котором вы могли бы переопределить clean метод формы вашей модели:

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.: В строке, где я прокомментировал, что это может не работать, вам придется немного отлаживать. Я не помню (и не могу проверить сейчас), возвращает ли cleaned_data кортеж или фактическое значение, или значение, читаемое человеком.

Теперь, я полагаю, вы хотите, чтобы select в вашем HTML динамически изменялся. Для фронтенда вам понадобится немного JavaScript. Есть много способов, как сделать это с помощью JS, но вот один из них:

(в вашем шаблоне, между тегами <script>)

var selectAnimal = document.getElementById("select-animal");
var selectFood = document.getElementById("select-food");

selectAnimal.addEventListener("change", function() {
    if(this.value == "a")
    {
        // Code to remove from food-select the "Chocolate option"
        for (var i=0; i<selectFood.length; i++) {
            if (selectFood.options[i].value == 'a')
                selectFood.remove(i);
        }
    }
    else {
        if (selectFood.length <= 3){
            option = document.createElement("option");
            option.text = "chocolate";
            option.value = "a";
            selectFood.add(option);
        }
    }
});

N.B.: Не самый лучший код, особенно if length <= 3, но неважно, вы поняли идею

Вернуться на верх