Django管理员。显示分层下拉过滤器

时间:2011-02-07 03:40:59

标签: python django django-admin

我有以下型号:

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管理员会生成包含城市下拉列表的公司创建表单。但是为了改善用户体验,我希望用户首先选择州,然后城市下拉列表将填充来自该州的城市。有没有一种标准的方法呢?

2 个答案:

答案 0 :(得分:1)

弯曲管理员并不容易,但它只是另一个django应用程序,尽管它非常复杂。我通常做这样的事情:

  1. Make a custom admin template for the model in question(覆盖change_form.html)。
  2. 创建一个ajax网址,返回按州ID过滤的城市小部件。
  3. 在状态更改时使用类似jQuery的内容替换City小部件。
  4. Django admin Javascript已经使用了jQuery库。为了避免与用户脚本冲突,Django的jQuery被命名为django.jQuery。因此,您不必包含第二个副本,您可以在更改列表上使用django.jQuery对象并添加/编辑视图。

答案 1 :(得分:1)

你需要创建一个自定义小部件来选择City模型(也就是说,你的模型应该FK到City而不是State),这个小部件包含两个Select字段,第一个包含Sstates,第二个包含Sstates选择一个州(您需要插入一个视图,根据州ID返回城市,以填充您的城市选择)。

您应该将媒体内部类的小部件设置为链接两个选择的特定.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);

我在一个应用程序中做了类似的事情,我在本地使用我的项目(可变深度最多三个级别),最终的解决方案有点毛茸茸,因为它必须支持每页多个小部件,动态小部件(用于内联) ),templatetags以各种形式呈现小部件等。