我的Django应用程序中有一个模型Layout
,其中包含以下字段:
meta_layout
上的ForeignKey
- MetaLayout
name
- CharField
edited
- DateTimeField
is_active
- BooleanField
我使用此模型有两个视图 - 一个名为NewLayout
,另一个EditLayout
每个子类标准CreateView
和UpdateView
。在EditLayout
视图中,我想使用一些与NewLayout
中使用的表单相同的特殊表单(对于此模型,它只是简单ModelForm
),但具有meta_layout
选择字段显示属性已禁用=“已禁用”(ed用户只能为每个布局选择一次meta_layout - 创建时)。好的,我可以创建自定义ModelForm
,其中meta_layout
字段的窗口小部件具有所需的属性,但问题实际上是当在表单字段上设置此类属性时,将不会发送任何带有请求的值< / strong> - 所以我的验证无法尝试检查此字段的值,而select元素不支持“readonly”属性,这将是合适的。
我找到了一些非常丑陋的黑客来解决这个问题:
#Here is my Form:
class LayoutEditForm(forms.ModelForm):
meta_layout = forms.ModelChoiceField(
queryset=MetaLayout.objects.all(),
widget=forms.Select(attrs=dict(disabled='disabled')),
empty_label=None,
required=False) # if required=True validation will fail
# because value is not supplied in POST
class Meta:
fields = ('meta_layout', 'name', 'is_active')
model = Layout
class EditLayout(UpdateView):
...
# And one modified method from my View-class
def get_form_kwargs(self):
kwargs = super(EditLayout, self).get_form_kwargs()
# actually POST parameters
if kwargs.has_key('data'):
# can't change QueryDict itself - it's immutable
data = dict(self.request.POST.items())
# emulate POST params from ModelChoiceField
data['meta_layout'] = u'%d' % self.object.meta_layout.id
kwargs['data'] = data
return kwargs
但我相信它不是非Django,非Pythonic而且不是一个好的编程风格,而不是做这么简单的事情。你能建议更好的解决方案吗?
编辑:
哦,我找到了不那么难看的解决方案:在我的表单类中添加了这个:
def clean_meta_layout(self):
return self.instance.meta_layout
但我仍然愿意接受建议) - 我可能错过了什么吗?