如何在创建对象时允许用户填充字段(“添加”页面),然后在“更改”页面访问时将其设置为只读?
答案 0 :(得分:10)
我找到的最简单的解决方案是覆盖ModelAdmin的get_readonly_fields函数:
class TestAdmin(admin.ModelAdmin):
def get_readonly_fields(self, request, obj=None):
'''
Override to make certain fields readonly if this is a change request
'''
if obj is not None:
return self.readonly_fields + ('title',)
return self.readonly_fields
admin.site.register(TestModel, TestAdmin)
对于添加页面,对象将是none,并且对于更改页面,对象将是您的模型的实例。 编辑:请注意这是在Django == 1.2
上测试的答案 1 :(得分:3)
你的问题要解决两件事。
不存在于Django中,但您可以自己实现,this blog post可以提供帮助。
我猜您正在寻找管理网站上下文中的解决方案(否则,只需在视图中使用2种不同的表单)。
您最终可能会覆盖add_view
中的change_view
或ModelAdmin
,并在其中一个视图中使用其他形式,但我担心您最终会遇到可怕的负担重复的代码。
我能想到的另一个解决方案是,在传递instance
参数(即:编辑情况)时,将在实例化时修改其字段的表单。假设你有一个ReadOnlyField
类,那会给你类似的东西:
class MyModelAdminForm(forms.ModelForm):
class Meta:
model = Stuff
def __init__(self, *args, **kwargs):
super(MyModelAdminForm, self).__init__(*args, **kwargs)
if kwargs.get('instance') is not None:
self.fields['title'] = ReadOnlyField()
在此处,模型title
中的字段Stuff
在管理网站的更改页面上是只读的,但在创建表单上是可编辑的。
希望有所帮助。
答案 2 :(得分:2)
您可以编辑该模型的保存方法以处理此类要求。例如,您可以检查字段是否已包含某个值,如果包含,则忽略新值。
答案 3 :(得分:1)
一个选项是override or replace该特定模型的change_form模板。