django admin如何在只读字段上显示小部件
Posted
技术标签:
【中文标题】django admin如何在只读字段上显示小部件【英文标题】:django admin how to display widget on readonly field 【发布时间】:2013-01-27 18:29:37 【问题描述】:当字段为只读时,我想在 django admin 的字段上显示我的小部件。
admin.py
class AudioTrackAdminInline(admin.StackedInline):
model = AudioTrack
form = AudioTrackForm
readonly_fields = ('file',)
forms.py
class AudioTrackForm(forms.ModelForm):
class Meta:
model = AudioTrack
widgets = 'file': MediaFileInput, # my widget
当文件不是只读时,它会显示小部件 OK。但是当我将它包含为只读时,我会看到文本行。 (如果只读,Django 不会使用我的表单)
如何让它在只读字段中使用表单?
或
如果我将我的字段设置为只读,如何显示另一个小部件?
【问题讨论】:
【参考方案1】:我会说这是一个功能。
当字段设置为只读时,Django 使用display_for_field
函数对结果进行硬编码,您无法自定义它。
另一种方法是不将该字段设置为只读并覆盖formfield_for_dbfield
,这是一个未记录的ModelAdmin
方法,并根据您的需要采取行动。
【讨论】:
覆盖formfield_for_dbfield
是危险的,因为用户可以提交POST
并篡改您打算只读的字段(或仅使用检查器启用它)。【参考方案2】:
另一种更灵活的解决方案是设置您希望以只读模式呈现的那些字段的“禁用”属性,覆盖您的管理类的 get_form(...)
方法:
def get_form(self, *args, **kwargs):
form = super(SupplierAdmin, self).get_form(*args, **kwargs)
for field_name in self.fake_readonly_fields:
form.base_fields[field_name].disabled = True
return form
请注意,我使用只读字段的名称不是来自通常的 self.readonly_fields
,而是来自我命名为 self.fake_readonly_fields
的不同数组,以避免名称重叠
建议的解决方案(使用formfield_for_dbfield
)的限制是,以同样的方式呈现给定类型的所有数据库字段,无论它是否应该是只读的。如果您的整个表单应该是只读的,那么这种方式是可行的,但是如果您处理的是一半只读一半不是的表单,最好依赖disabled
属性。
关于我的答案的更多细节:django modeladmin, readonly_fields and boolean fields
【讨论】:
这应该使用disabled
Field
属性,因为并非所有小部件都支持 (html) 属性(例如使用 django.contrib.gis.forms.fields.PointField
),并且它可以由用户更改!所以应该使用form.base_fields[field_name].disabled = True
。
如果是相关字段(例如ForeignKey
字段),您可能需要删除添加/编辑/删除相关对象的小按钮。这可以通过设置适当的表单域小部件属性来完成,如here 所述。以上是关于django admin如何在只读字段上显示小部件的主要内容,如果未能解决你的问题,请参考以下文章