根据另一个下拉框选择在Django管理中预填充下拉框

0 投票
3 回答
878 浏览
提问于 2025-04-15 23:42

我有这样的模型:

class User(models.Model): 
    Switch = models.ForeignKey(Switch, related_name='SwitchUsers') 
    Port = models.ForeignKey(Port) 
class Switch(models.Model): 
    Name = models.CharField(max_length=50) 
class Port(models.Model): 
    PortNum = models.PositiveIntegerField() 
    Switch = models.ForeignKey(Switch, related_name = "Ports") 

当我在管理界面选择可用的开关时,我希望端口能够自动填充与所选开关相关的端口。根据我的理解,我需要创建一些JavaScript脚本来实现这个自动填充。不幸的是,我没有这方面的经验,我希望尽可能简单,不想重写整个Django的管理界面。只想为一个字段添加这个功能。

你能帮我解决这个问题吗?谢谢。

3 个回答

0

我知道这是一种快捷方式,可能不是最优的,但你有没有考虑把两个选择框合并成一个,使用分组选项(optgroups)呢?这样你就不用写自定义的JavaScript了。

因为这是一个外键(ForeignKey),如果他们选择了一个端口,你就知道对应的交换机(switch)是什么。你可以把交换机作为分组选项,值设为"",这样他们在只选择交换机后就不能保存。以下是我想到的步骤:

  1. 自定义表单字段,去掉switch
  2. port表单字段的标题改为交换机/端口
  3. port表单字段的choices改为一个元组,这个元组是从交换机和端口生成的。
  4. 添加一个自定义的保存视图,从端口获取交换机,并把用户的交换机设置为这个值。

如果用户或相关人员觉得这样可以接受,这是一种避免涉及较多JavaScript编程的方法,同时也需要一些Django编程的知识。

0

你可以找到比上面提供的更简单的解决方案。与其修改模板并把 JSON 放在标签里,不如把这个 JSON 放在你的 JS 文件的开头,同时在那里面加上 $().ready 的调用,这样可以给下拉框的变化事件添加监听器,然后把这个 JS 文件引入到 ModelAdmin 的媒体部分。

class MyAdmin(admin.ModelAdmin):
    class Media:
        js = ("my_code.js",)

小贴士:可以使用 Firebug 或 Chrome 检查器来查看表单上 HTML 字段的真实名称。

1

你说得对,确实需要一些JavaScript来实现这个功能。你不需要完全重写Django的管理界面,只需要对它进行一些定制。要做到这一点,有几个步骤需要注意。

可以从这里开始了解:http://docs.djangoproject.com/en/1.2/ref/contrib/admin/#modeladmin-objects

要添加你的JavaScript,可以使用Media类

Django的表单会给所有的输入框分配一致的ID,这样你就可以很方便地操作它们。不过,你需要把“关系”传递给客户端。也就是说,在客户端你需要知道哪些Ports对应哪些Switch。根据你的数据量,有几种方法可以做到这一点:

  • 把关系编码成JSON格式,然后通过定制你的模型的管理模板输出到一个标签中。

  • 使用Ajax。你需要至少一个额外的视图,它接收一个Switch并返回与之对应的Ports的JSON列表(或类似的格式)。

JavaScript的操作应该比较简单:你需要把下拉框的onChange()事件绑定到一个函数,这个函数会在Port下拉框中只保留相关的Ports

我建议使用jQuery来进行DOM操作。

撰写回答