根据另一个下拉字段自定义django管理字段



我有一个简单的Django应用程序,有三个模型:

class Category(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(("Description"))

class ItemType(models.Model):
name = models.CharField(max_length=100)
description = models.TextField(("Description"))
category = models.ForeignKey(Category, on_delete=models.CASCADE)
class Plant(models.Model):
category = models.ForeignKey(Category , on_delete=models.SET_NULL , null=True)
type = models.ForeignKey(ItemType, on_delete=models.SET_NULL,null = True)
name = models.CharField()

我需要的是在管理面板中,当我选择一个类别时,类型下拉列表是基于这个筛选的。例如,我有类别1和类别2,类型1与类别1相关,类型2与类别2相关

前几天我不得不这么做,这有点痛苦,但可行,自从我提出这个方法以来,我已经用了好几次了。

步骤

  1. 将所需信息添加到render_change_form中的上下文中

以你为例,我想你会想要一些类似的东西

def render_change_form(self, request, context, add=False, change=False, form_url='', obj=None):
# Implement get_map to return a hierarchical dict that represents your category, item type, and plant 
context['map'] = self.get_map()
return super().render_change_form(request, context, add, change, form_url, obj)
  1. 隐藏尚未归档的行
window.addEventListener('DOMContentLoaded', (event) => {
django.jQuery("div.field-item_type").css('display', '');
django.jQuery("div.field-plant").css('display', '');
});
  1. 添加事件侦听器以更新相关字段
# When category is changed, you'll need to update options for item_type  and plant
django.jQuery("select[name=category]").change(function () {
let category = django.jQuery(this)
update_item_type(category)
update_plant(django.jQuery('select[name=category]'))
});
# When item_type is changed, you'll only need to plant options
django.jQuery("select[name=item_type]").change(function () {
let item_type = django.jQuery(this)
update_plant(item_type)
});
  1. 实现update_item_typeupdate_plant以更新相应字段上的选项

它们看起来像这个

function update_item_type(plant) {
let starting_item_type = django.jQuery("select[name=item_type]").val()
if (plant.val() === '') {
django.jQuery("div.field-item_type").css('display', 'none');
} else {
let item_type_dict = {{ item_type_dict|safe }};
let item_type_dom = django.jQuery('#id_item_type');
item_type_dom.text('')
django.jQuery.each(item_type_dict[plant.val()], function(index, element) {
item_type_dom.append('<option value="' + element[0] + '">' + element[1] + '</option>');
});
django.jQuery("div.field-item_type").css('display', '');
django.jQuery("select[name=item_type]").val(starting_item_type)
}
}

从Django的土地上访问你的字典,就像这个

let map = {{ map|safe }};

跟进

我可能应该创建一个Django包来自动完成这项工作。如果有人已经知道了,我很想听听。

最新更新