2

Layout次のフィールドを持つ Django アプリで モデルを取得しました。

  • meta_layout-ForeignKeyモデル上MetaLayout
  • name-CharField
  • edited-DateTimeField
  • is_active-BooleanField

そして、このモデルを使用する 2 つのビューがNewLayoutありEditLayoutます。ビューでは、使用されているフォームと同じように見える特別なフォームを使用したい(これは、このモデルでは単純です) が、属性 disabled="disabled"で表示される選択フィールドがあります(ed ユーザーは、レイアウトごとに一度だけ meta_layout を選択できます -作成中)。OK、フィールドのウィジェットに必要な属性があるカスタムを作成できますが、実際の問題は、そのような属性がフォームフィールドに設定されている場合、リクエストで値を送信しないことですCreateViewUpdateViewEditLayoutNewLayoutModelFormmeta_layoutModelFormmeta_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