2

我的 Django 应用程序中有一个模型Layout,其中包含以下字段:

  • meta_layout-ForeignKey在模型上MetaLayout
  • name-CharField
  • edited-DateTimeField
  • is_active-BooleanField

我有两个使用这个模型的视图——一个被调用NewLayout,另一个被调用,EditLayout每个子类化标准CreateViewUpdateView相应的。在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

但我仍然愿意接受建议) - 我可能错过了什么吗?

4

0 回答 0