在 Django 中,根据模型中其他字段中选择的值删除选择字段下拉列表中的选项
In Django, remove options in a choice-field dropdown based on the value selected in other field in a model
我是 Django 的新手,非常感谢任何帮助,如何根据前一个字段限制一个字段中的选择选项。例如,如果我 select 'dog' 表示动物,我想从 FOOD_CHOICE 中删除 'chocolate'。谢谢!!!
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,您应该在模型表单或模型清理方法中进行验证,并在那里引发 ValidationError
。
这是一个示例,您可以在其中 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.: 在我评论说它可能不起作用的那一行,你必须稍微调试一下。我不记得(我现在无法测试)cleaned_data
returns 是元组还是实际值,还是人类可读的值。
现在,我猜您希望 HTML 中的 select 动态更改。对于前端,您需要做一些 JavaScript。有很多方法可以用 JS 来实现,但这里是一个:
(在您的模板中,在 <script>
标签之间)
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);
}
}
});
我是 Django 的新手,非常感谢任何帮助,如何根据前一个字段限制一个字段中的选择选项。例如,如果我 select 'dog' 表示动物,我想从 FOOD_CHOICE 中删除 'chocolate'。谢谢!!!
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,您应该在模型表单或模型清理方法中进行验证,并在那里引发 ValidationError
。
这是一个示例,您可以在其中 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.: 在我评论说它可能不起作用的那一行,你必须稍微调试一下。我不记得(我现在无法测试)cleaned_data
returns 是元组还是实际值,还是人类可读的值。
现在,我猜您希望 HTML 中的 select 动态更改。对于前端,您需要做一些 JavaScript。有很多方法可以用 JS 来实现,但这里是一个:
(在您的模板中,在 <script>
标签之间)
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);
}
}
});