我的 Django 应用程序中有一个模型Layout
,其中包含以下字段:
meta_layout
-ForeignKey
在模型上MetaLayout
name
-CharField
edited
-DateTimeField
is_active
-BooleanField
我有两个使用这个模型的视图——一个被调用NewLayout
,另一个被调用,EditLayout
每个子类化标准CreateView
和UpdateView
相应的。在EditLayout
视图中我想使用一些看起来与使用的表单相同的特殊表单NewLayout
(这对于这个模型来说很简单ModelForm
)但是meta_layout
选择字段显示为属性 disabled="disabled"(ed 用户只能为每个布局选择 meta_layout 一次 -在创建它时)。好的,我可以在字段的ModelForm
小部件meta_layout
具有所需属性的地方创建自定义,但问题实际上是当在表单字段上设置此类属性时,它不会发送任何带有请求的值- 所以我的验证尝试检查该字段的值失败,并且选择元素不支持“只读”属性,这在这里会很好。
我发现了一些非常丑陋的黑客来解决这个问题:
#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
但我仍然愿意接受建议) - 我可能错过了什么吗?