如何在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时,当用户从下拉菜单中选择类别后,我想限制“项目”下拉菜单中的选择数量。如果用户选择了另一个类别,那么项目的选择也应该相应更新。我希望在客户端就限制项目的选择,甚至在服务器进行表单验证之前就完成。这是为了提高用户体验,因为项目列表可能有1000多个,通过类别来缩小选择范围会让管理变得更简单。
有没有什么“django方式”可以做到这一点,还是说只能用自定义的JavaScript呢?
3 个回答
0
你需要有一种不依赖服务器的方式来过滤这些对象。要不然,你可以在选择后重新加载页面(这通常也是用JavaScript来实现的)。
否则,就没有办法从服务器获取到你想要的数据子集到客户端。
7
这里有一个叫做 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)
10
这里有一些基于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>
你需要一个视图(view),它会在 /items/ 这个网址被调用,并提供一个有效项目的JSON列表。
你可以通过使用模型管理媒体定义将这个功能添加到你的管理后台。