我正在尝试编写一个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不起作用。
答案 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