2009-06-12 4 views
3
class StatusForm(ModelForm): 

    bases = forms.ModelMultipleChoiceField(
      queryset=Base.objects.all(), #this should get overwritten 
      widget=forms.SelectMultiple, 
     ) 

    class Meta: 
     model = HiringStatus 
     exclude = ('company', 'date') 

    def __init__(self, *args, **kwargs): 
     super(StatusForm, self).__init__(*args, **kwargs) 
     if kwargs.has_key('bases_queryset'): 
      self.fields['bases'].queryset = kwargs['bases_queryset'] 

私は、私はそうのようなフォームを作成することができますこのフォームにオプションを追加する追加:クラスへ** kwarg

form = StatusForm(bases_queryset=Base.objects.filter([...]) 

しかし、私は何とかそのキーワードを「追加」する必要がありますがそれが認識されるようにクラスへの引数。あなたはスーパーコンストラクタにkwargsからを開梱しているためだ

__init__() got an unexpected keyword argument 'bases_queryset'

答えて

11

:彼らは道それが今、私はこのエラーを取得しています。 @Keeperが示すように、あなたはスーパークラスにあなたの「新しい」キーワード引数を渡してはいけません...

+8

より良いアプローチを単純です: bases_queryset = kwargs.pop(「bases_queryset」、なし) これは、キーを辞書から削除し、そこに存在する場合はその値を返し、キーが存在しない場合はNoneに初期化します。 –

+0

はい、それは良いです:私は完全に.popメソッドを忘れてしまった – Keeper

11

if kwargs.has_key('bases_queryset'): 
    bases_queryset = kwargs['bases_queryset'] 
    del kwargs['bases_queryset'] 

が、それは理想的なソリューションではありません。 スーパーを呼び出す前にこれを入れてみてください。

bqs = kwargs.pop('bases_queryset', None) 

とその__init__呼び出しの後、代わりにhas_keyを(そしてもちろん、代わりにkwargs['bases_queryset']bqsを使用)を使用してのif bqs is not None:を確認してください。ベストは、あなたがスーパーの__init__を呼び出す前に、行うことかもしれません。

興味深い代替アプローチは、「選択呼び出し」高次関数を作ることです。あなたが位置と名前の両方の引数を持っていればちょっと混乱します。(常にです.-)メタプログラミングにはちょっと面倒ですので、説明を簡単にするため、選択的に呼び出す関数は "普通の"すなわち、**kもありません)。今、このアプローチには

import inspect 

def selective_call(func, **kwargs): 
    names, _, _, _ = inspect.getargspec(func) 
    usable_kwargs = dict((k,kwargs[k]) for k in names if k in kwargs) 
    return func(**usable_kwargs) 

は、あなたの__init__で、代わりに直接、スーパーの__init__を呼び出すので、あなたは selective_call(super_init, **kwargs)を呼び出すと、この高次機能が必要な「剪定」をやらせると思います。 (!もちろん、あなたもああ...、それは位置と名前の両方の引数を処理するために、メシエようにする必要があります - )

関連する問題