我正在学习django形式,并想知道如何使模型表单仅生成显示。
models.py
class Person(models.Model):
first_name = models.CharField(max_length=40, null=True)
last_name = models.CharField(max_length=40, null=True)
#more fields
forms.py
class PersonForm(ModelForm):
class Meta:
model = Person
要生成包含数据库中某些现有数据的表单:
person=Person.objects.get(id=someid)
person_form = PersonForm(instance = person)
表单中的所有字段都可在页面中编辑。但是,我只是想显示数据。
在StackOverflow中进行了一些搜索之后,我发现了一个类似的解决方案how to show a django ModelForm field as uneditable,它教会了如何设置单个字段。
但我想让整个表格无法编辑。有没有更好的方法,而不是将所有字段逐个设置为不可编辑?
非常感谢你的帮助。
更新:我发现流动的代码有助于使表单无法使用,但仍不确定这是否是正确的方法。
for field in person_form.fields:
person_form.fields[field].widget.attrs['readonly'] = True
感谢您的建议。
答案 0 :(得分:1)
表单上没有名为editable
或类似内容的属性,可以对所有字段执行操作。所以,你不能在表单层面上这样做。
此外,django表单中使用的Field
类也没有此类属性,因此无法设置此类属性并使该字段为只读。因此,您必须对表单__init__
中表单的字段进行操作。
class PersonForm(ModelForm):
class Meta:
model = Person
def __init__(self, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
for name, field in self.fields.iteritems():
field.widget.attrs['readonly'] = 'true'
如果您只想使某些字段不可编辑,请更改__init__
。
def __init__(self, *args, **kwargs):
super(PersonForm, self).__init__(*args, **kwargs)
uneditable_fields = ['first_name', 'last_name']
for field in uneditable_fields:
self.fields[field].widget.attrs['readonly'] = 'true'
答案 1 :(得分:1)
也许另一个解决方案,不必做任何处理,只需显示这样..
<table border='1'>
{% for field in form%}
<tr>
<td>{{field.label}}</td>
<td>{{field.value}}</td>
</tr>
{% endfor%}
</table>
答案 2 :(得分:0)
我知道,老问题,但由于本周我有同样的问题,这可能对其他人有所帮助。
此技术仅在您希望整个表单只读时才有效。它会覆盖任何发布的数据(请参阅def clean(self)
)并将窗口小部件属性设置为只读。
注意:将窗口小部件属性设置为readonly不会阻止更改模型对象实例。
class MyModelForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyModelForm, self).__init__(*args, **kwargs)
if self.is_readonly():
for k,f in self.fields.iteritems():
f.widget.attrs['readonly'] = True
def clean(self):
if self.is_readonly():
return {}
return super(CompanyQuestionUpdateForm, self).clean()
def is_readonly(self, question):
if your_condition:
return True
return False
class Meta:
model = MyModel
答案 3 :(得分:0)
可以实现字段小部件来呈现包含在div或td中的绑定ModelForm字段值,示例实现是否存在
https://github.com/Dmitri-Sintsov/django-jinja-knockout/blob/master/django_jinja_knockout/widgets.py
# Read-only widget for existing models.
class DisplayText(Widget):
然后可以实现一个表单元类,它将自动为所有ModelForm字段设置字段小部件为DisplayText:
https://github.com/Dmitri-Sintsov/djk-sample/search?utf8=%E2%9C%93&q=DisplayModelMetaclass
class ClubDisplayForm(BootstrapModelForm, metaclass=DisplayModelMetaclass):
class Meta(ClubForm.Meta):
widgets = {
'category': DisplayText()
}
随意使用或开发自己的小部件/窗体元类版本。
有关django bug票证的只读ModelForms的讨论:
https://code.djangoproject.com/ticket/17031
关闭为“Froms用于处理数据,而不是渲染数据。”
但我认为这是错误的原因:
ModelForms不仅处理数据,还将表单映射到模型。只读映射是映射的子集。
内联表单集和只读内联表单集更加方便,手动渲染关系会带来很多负担。
基于类的视图可以共享公共模板以显示和编辑ModelForms。因此只读显示ModelForms会增加DRY(Django关键原则之一)。