Django管理员。显示分层下拉过滤器
问题内容:
我有以下模型:
from django.db import models
class State(models.Model):
name = models.CharField(max_length=30)
abbreviation = models.CharField(max_length=2)
def numberOfCities(self):
return self.city_set.count()
def __unicode__(self):
return u"{0} - {1}".format(self.abbreviation, self.name)
class City(models.Model):
name = models.CharField(max_length=40)
state = models.ForeignKey(State)
class Meta:
verbose_name_plural = 'Cities'
def __unicode__(self):
return self.name
class Company(models.Model):
name = models.CharField(max_length=60)
description = models.CharField(max_length=1000)
city = models.ForeignKey(City)
class Meta:
verbose_name_plural = 'Companies'
def __unicode__(self):
return self.name;
如您所见,每个公司都与一个城市相关联,并且您可以期望Django管理员生成包含城市下拉列表的公司创建表单。但是,为了改善用户体验,我希望用户先选择州,然后在城市下拉列表中填充该州的城市。有这样做的标准方法吗?
问题答案:
您需要创建一个自定义小部件以选择City模型(也就是说,您的模型应FK到City而不是State),此小部件包含两个Select字段,第一个包含Sstate,第二个包含在选择中州(您需要插入一个视图以根据州ID返回城市以填充您选择的城市)。
您应该将窗口小部件Media内部类指向所有Selects链接的特定.js文件。
在ModelAdmin规范中,将字段的窗口小部件设置为刚创建的自定义窗口小部件,它将自动将其媒体添加到change_form模板中。
确保您的.js文件查找常规的JQuery对象并回退到django.JQuery,这样您就可以在管理员和整个站点中使用相同的小部件。
(function($) {
// Note that this function works only for one widget per page
$('#state').change(function(){
$('#city').load('/cities_by_state/', {id: this.value}); // the endpoint returns HTML
});
})(JQuery||django.JQuery);
我在本地用于项目的应用程序中做了类似的操作(可变深度最多为三个级别),最终的解决方案有点麻烦,因为它必须支持每页多个小部件,动态小部件(用于内联),模板标签以各种形式渲染小部件等