Как ограничить параметры поля выбора на основе другого поля выбора в django admin
У меня есть следующие модели:
class Category(models.Model):
name = models.CharField(max_length=40)
class Item(models.Model):
name = models.CharField(max_length=40)
category = models.ForeignKey(Category)
class Demo(models.Model):
name = models.CharField(max_length=40)
category = models.ForeignKey(Category)
item = models.ForeignKey(Item)
В интерфейсе администратора при создании нового Demo, после выбора пользователем категории из раскрывающегося списка, я хотел бы ограничить количество вариантов в раскрывающемся списке "items". Если пользователь выбирает другую категорию, то выбор пункта должен соответствующим образом обновляться. Я хотел бы ограничить выбор элементов прямо на клиенте, прежде чем он даже ударит проверку формы на сервере. Это для удобства использования, потому что список элементов может быть 1000+, способный сузить его по категориям, чтобы сделать его более управляемым.
Есть ли способ "django-way" для этого или пользовательский JavaScript только здесь?
Ответы
Ответ 1
Вот несколько javascript (на основе JQuery), чтобы изменить значения параметра элемента при изменении категории:
<script charset="utf-8" type="text/javascript">
$(function(){
$("select#id_category").change(function(){
$.getJSON("/items/",{id: $(this).val(), view: 'json'}, function(j) {
var options = '<option value="">-------- </option>';
for (var i = 0; i < j.length; i++) {
options += '<option value="' + j[i].optionValue + '">' + j[i].optionDisplay + '</option>';
}
$("#id_item").html(options);
$("#id_item option:first").attr('selected', 'selected');
})
$("#id_category").attr('selected', 'selected');
})
})
</script>
Вам нужно отобразить представление на /items/URL, который предоставляет список допустимых элементов JSON.
Вы можете подключить это к своему администратору, используя определения параметров файла admin.
Ответ 2
Существует django-smart-selects:
Если у вас есть следующая модель:
class Location(models.Model)
continent = models.ForeignKey(Continent)
country = models.ForeignKey(Country)
area = models.ForeignKey(Area)
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
И вы хотите, чтобы, если вы выберете континент, доступны только страны, расположенные на этом континенте, и то же самое для областей, где вы можете сделать следующее:
from smart_selects.db_fields import ChainedForeignKey
class Location(models.Model)
continent = models.ForeignKey(Continent)
country = ChainedForeignKey(
Country,
chained_field="continent",
chained_model_field="continent",
show_all=False,
auto_choose=True
)
area = ChainedForeignKey(Area, chained_field="country", chained_model_field="country")
city = models.CharField(max_length=50)
street = models.CharField(max_length=100)
Ответ 3
Я думаю, что JavaScript/AJAX будет лучшим подходом к этой проблеме.
Ответ 4
Вам понадобится какой-то механизм фильтрации объектов, не основанный на сервере. Либо это, либо вы можете перезагрузить страницу при выборе (что, скорее всего, будет выполнено на JavaScript).
В противном случае невозможно получить подмножество данных с сервера клиенту.