[英]how to show a django ModelForm field as uneditable
用django ModelForm
开始我的初步课程,我想给用户,能够编辑博客中的条目BlogEntry
有date,postedTime, title and content
。我想向用户展示一个显示所有这些字段的编辑表单,但只有title and content as editable
的。 date and postedTime should be shown as uneditable
。
class BlogEntry(models.Model):
title = models.CharField(unique=True,max_length=50)
description = models.TextField(blank=True)
date = models.DateField(default=datetime.date.today)
postedTime = models.TimeField(null=True)
...
为了添加条目,我以正常方式使用 ModelForm ..
class BlogEntryAddForm(ModelForm):
class Meta:
model = BlogEntry
...
但是如何创建编辑表单?我希望它show the date,postedTime as uneditable
(但仍将它们显示在表单上)并让用户编辑title and description
。
如果我使用, exclude in class Meta
日期和发布时间,这将导致它们不会出现在表单上。那么,我怎样才能将它们显示为不可编辑?
class BlogEntryEditForm(ModelForm):
class Meta:
model = BlogEntry
...?...
在表格 object 中,将字段的属性声明为readonly
:
form.fields['field'].widget.attrs['readonly'] = True
date
字段是表示条目首次创建的日期还是上次修改的日期? 如果首先使用auto_now_add
选项,则使用auto_now
。 那是:
date = models.DateField(auto_now_add=True)
将创建条目的date
设置为现在。
auto_now_add
使字段不可编辑。 对于其他情况,使用editable
选项使任何字段不可编辑。 例如
postedDate = models.TimeField(null=True, editable=False)
此外,您可能会将posted
的 boolean 字段添加到Entry
model,因此在张贴日期上设置auto_now
很postedDate
。 每次您修改 Entry 时,它都会将postedDate
设置为 now ,其中包括将posted
设置为True
时的一个。
我是这样实现的: https://djangosnippets.org/snippets/10514/此实现使用 model 实例的数据用于所有只读字段,而不是处理表单时获得的数据
在相同的代码下方,但使用他的示例
from __future__ import unicode_literals
from django.utils import six
from django.utils.encoding import force_str
__all__ = (
'ReadOnlyFieldsMixin',
'new_readonly_form_class'
)
class ReadOnlyFieldsMixin(object):
"""Usage:
class MyFormAllFieldsReadOnly(ReadOnlyFieldsMixin, forms.Form):
...
class MyFormSelectedFieldsReadOnly(ReadOnlyFieldsMixin, forms.Form):
readonly_fields = ('field1', 'field2')
...
"""
readonly_fields = ()
def __init__(self, *args, **kwargs):
super(ReadOnlyFieldsMixin, self).__init__(*args, **kwargs)
self.define_readonly_fields(self.fields)
def clean(self):
cleaned_data = super(ReadOnlyFieldsMixin, self).clean()
for field_name, field in six.iteritems(self.fields):
if self._must_be_readonly(field_name):
cleaned_data[field_name] = getattr(self.instance, field_name)
return cleaned_data
def define_readonly_fields(self, field_list):
fields = [field for field_name, field in six.iteritems(field_list)
if self._must_be_readonly(field_name)]
map(lambda field: self._set_readonly(field), fields)
def _all_fields(self):
return not bool(self.readonly_fields)
def _set_readonly(self, field):
field.widget.attrs['disabled'] = 'true'
field.required = False
def _must_be_readonly(self, field_name):
return field_name in self.readonly_fields or self._all_fields()
def new_readonly_form_class(form_class, readonly_fields=()):
name = force_str("ReadOnly{}".format(form_class.__name__))
class_fields = {'readonly_fields': readonly_fields}
return type(name, (ReadOnlyFieldsMixin, form_class), class_fields)
class BlogEntry(models.Model):
title = models.CharField(unique=True,max_length=50)
description = models.TextField(blank=True)
date = models.DateField(default=datetime.date.today)
postedTime = models.TimeField(null=True)
# all fields are readonly
class BlogEntryReadOnlyForm(ReadOnlyFieldsMixin, forms.ModelForm):
class Meta:
model = BlogEntry
# selected fields are readonly
class BlogEntryReadOnlyForm2(ReadOnlyFieldsMixin, forms.ModelForm):
readonly_fields = ('date', 'postedTime')
class Meta:
model = BlogEntry
class BlogEntryForm(forms.ModelForm):
class Meta:
model = BlogEntry
BlogEntryFormReadOnlyForm = new_readonly_form_class(BlogEntryForm, readonly_fields=('description', ))
这将防止任何用户破解请求:
self.fields['is_admin'].disabled = True
自定义表单示例:
class MemberShipInlineForm(forms.ModelForm):
is_admin = forms.BooleanField(required=False)
def __init__(self, *args, **kwargs):
super(MemberShipInlineForm, self).__init__(*args, **kwargs)
if 'instance' in kwargs and kwargs['instance'].is_group_creator:
self.fields['is_admin'].disabled = True
class Meta:
model = MemberShip
fields = '__all__'
从文档中,
class BlogEntryEditForm(ModelForm):
class Meta:
model = BlogEntry
readonly_fields = ['date','postedTime']
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.