Django ModelChoiceField没有在管理员中添加attrs到html

时间:2011-06-24 20:20:32

标签: django-admin django-forms

我正在尝试编写一个Django应用程序,并且在为我的某个模型定制管理员时遇到一些困难。

以下是我正在使用的模型的简化版本:

class Server(django.db.models.Model):
    name = django.db.models.CharField(max_length=40)
    is_virtual = django.db.models.BooleanField()
    host = django.db.models.ForeignKey(u'self', blank=True, null=True)

以下是我尝试与管理员联系的表单:

class ServerAdminForm(forms.ModelForm):
    class Meta:
        model = models.Server

    def __init__(self, *args, **kwargs):
        super(ServerAdminForm, self).__init__(*args, **kwargs)
        if not self.instance.is_virtual:
            # I don't know why these are not working
            self.fields['host'].widget.attrs['disabled'] = 'disabled'
            self.fields['host'].widget.attrs['readonly'] = True

以下是管理员代码(实际上还有更多字段和其他字段集):

class ServerAdmin(admin.ModelAdmin):
    fieldsets = (
        (None, {
            'fields': ('name', 'is_virtual', 'host')
        }),
    )
    form = admin_forms.ServerAdminForm
    save_as = True

我的目标是仅在is_virtual为True时让管理员显示主机字段。我尝试从字段中删除主机,并在上面的 init 表单中将其设置为none,但这两个都崩溃了,因为我在字段集中列出了它。

所以我的第一个问题是:是否有一种基于实例动态修改字段集的简洁方法?我尝试了几个小时的方法,但谷歌和django文档无处可去。

在使用上述方法失败后,我决定在is_virtual为False时尝试禁用ModelChoiceField。这是我上面的表单代码。当我单步执行代码时,所有内容似乎都设置正确,但是当我查看html源时,我看不到禁用或只读属性。我尝试将主机切换到CharField以查看是否有任何改变,当我查看html时,属性已设置。

我不确定我是否遗漏了文档中的某些内容,说您无法禁用ModelChoiceFields,或者我只是做错了什么,但我很感激有关如何禁用ModelChoiceField的任何建议。

所以我正在寻找一种基于实例动态修改字段集的方法或者一种禁用ModelChoiceField的方法。如果您认为有更好的方法可以解决这个问题,我也会采取其他方法。

提前感谢您的帮助。

更新

我能够使用所选答案中的javascript方法获得所需的结果。

然而,我仍然很好奇为什么我采用的方法,使用self.fields ['host']。widget.attrs,对于ModelChoiceField不起作用。

1 个答案:

答案 0 :(得分:1)

如果要在点击时切换字段显示,则应使用javascript。请参阅:How To Collapse Just One Field in Django Admin?

如果没有,您可以使用__init__中的base_fields动态创建或修改表单:

    if not self.instance.is_virtual:
        ServerAdminForm.host = django.db.models.ForeignKey(u'self', blank=True, null=True)
        ServerAdminForm.base_fields['host'] = ServerAdminForm.host

请参阅:Monkey patching a Django form class?