Layout
次のフィールドを持つ Django アプリで モデルを取得しました。
meta_layout
-ForeignKey
モデル上MetaLayout
name
-CharField
edited
-DateTimeField
is_active
-BooleanField
そして、このモデルを使用する 2 つのビューがNewLayout
ありEditLayout
ます。ビューでは、使用されているフォームと同じように見える特別なフォームを使用したい(これは、このモデルでは単純です) が、属性 disabled="disabled"で表示される選択フィールドがあります(ed ユーザーは、レイアウトごとに一度だけ meta_layout を選択できます -作成中)。OK、フィールドのウィジェットに必要な属性があるカスタムを作成できますが、実際の問題は、そのような属性がフォームフィールドに設定されている場合、リクエストで値を送信しないことですCreateView
UpdateView
EditLayout
NewLayout
ModelForm
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
しかし、私はまだ提案を受け付けています) - 何か見逃したことがありますか?