7

フォームクラス(巨大なDjangoアプリのどこか深いところ)が与えられます。

class ContactForm(forms.Form):
    name = ...
    surname = ...

また、フォームクラス自体を拡張または変更せずに、このフォームに別のフィールドを追加したい場合、次のアプローチが機能しないのはなぜですか。

ContactForm.another_field = forms.CharField(...)

(私の最初の推測では、Djangoが使用するメタクラスハッカーは、フォームクラスが初めて構築されたときにのみ適用されます。そうであれば、これを克服するためにクラスを再宣言する方法はありますか?)

4

1 に答える 1

9

いくつかの適切な定義はで発生しdjango/forms/forms.pyます。彼らです:

  1. class BaseForm
  2. class Form
  3. class DeclarativeFieldsMetaclass
  4. def get_declared_fields

get_declared_fieldsから呼び出さDeclarativeFieldsMetaclassれ、作成カウンターでソートされたフィールドインスタンスを使用してリストを作成します。次に、基本クラスのフィールドをこのリストの前に追加OrderedDictし、フィールド名がキーとして機能するインスタンスとして結果を返します。DeclarativeFieldsMetaclass次に、この値を属性base_fieldsに固定し、を呼び出してtypeクラスを作成します。次に、クラスをのmedia_property関数に渡しwidgets.py、戻り値をmedia新しいクラスの属性に付加します。

media_propertyアクセスごとにメディア宣言を再構築するプロパティメソッドを返します。ここでは関係ないのではないかと思いますが、間違っている可能性があります。

いずれにせよ、Media属性を宣言していない場合(および基本クラスのいずれも宣言していない場合)Media、コンストラクターへの引数のない新しいインスタンスのみが返されます。新しいフィールドにモンキーパッチを適用するのは、手動で挿入するのと同じくらい簡単なはずです。フィールドにbase_fields

ContactForm.another_field = forms.CharField(...)
ContactForm.base_fields['another_field'] = ContactForm.another_field

次に、各フォームインスタンスは、のメソッドに含まれるdeepcopyのを取得します。HTH。base_fieldsform_instance.fields__init__BaseForm

于 2010-10-14T07:02:43.430 に答える