1

Django docsによると、ChoiceFieldはan iterable of two tuples, "or a callable that returns such an iterable"をフィールドの選択として使用できます。ビューから、カスタムの「選択肢」をフォームのChoiceFieldに渡すにはどうすればよいですか?

私は私のフォーム内ChoiceFieldsを定義した:ここでは、私のmodels.py

class PairRequestView(FormView): 
    form_class = PairRequestForm 

    def get_initial(self): 
     requester_obj = Profile.objects.get(user__username=self.request.user) 
     accepter_obj = Profile.objects.get(user__username=self.kwargs.get("username")) 

     # `get_favorites()` is the object's method which returns a tuple. 
     favorites_set = requester_obj.get_favorites() 

     initial = super(PairRequestView, self).get_initial() 

     initial['favorite_choices'] = favorites_set 

     return initial 

次のとおりです。ここで

class PairRequestForm(forms.Form): 
    favorite_choices = forms.ChoiceField(choices=[], widget=RadioSelect, required=False) 

は、私は、カスタムの選択肢のタプルを渡すためにしようとしています図、上記のタプルを返すメソッド:

def get_favorites(self): 
     return (('a', self.fave1), ('b', self.fave2), ('c', self.fave3)) 

私の理解から、フォームをあらかじめ入力したい場合は、get_initial()をオーバーライドしてデータを渡します。フォームのfavorite_choicesの初期データを呼び出し可能に設定しようとしました。呼び出し可能なのはfavorites_setです。現在のコードで

は、私は私がすることができ、私自身の選択でRadioSelect ChoiceFieldに事前どう'tuple' object is not callable

の誤差を与えられたのですか?

編集:私もget_initial方法は、フォームのフィールドの初期値を設定するために作られinitial['favorite_choices'].choices = favorites_set

答えて

1

設定しようとしました。利用可能な番号をchoicesに設定したり、フィールド属性を変更することはできません。

が正常にフォームにあなたのビューから、あなたの選択肢を渡すために、あなたはあなたのビューで get_form_kwargsメソッドを実装する必要があります。
class PairRequestView(FormView): 
    form_class = PairRequestForm 

    def get_form_kwargs(self): 
     """Passing the `choices` from your view to the form __init__ method""" 

     kwargs = super().get_form_kwargs() 

     # Here you can pass additional kwargs arguments to the form. 
     kwargs['favorite_choices'] = [('choice_value', 'choice_label')] 

     return kwargs 

そして、あなたの形で

は、 __init__方法でkwargsから引数から選択を取得しますフィールドに選択肢を設定します。

class PairRequestForm(forms.Form): 

    favorite_choices = forms.ChoiceField(choices=[], widget=RadioSelect, required=False) 

    def __init__(self, *args, **kwargs): 
     """Populating the choices of the favorite_choices field using the favorites_choices kwargs""" 

     favorites_choices = kwargs.pop('favorite_choices') 

     super().__init__(*args, **kwargs) 

     self.fields['favorite_choices'].choices = favorites_choices 

そして、voilà!

+0

'self.fields []。choices'を編集する前に' super().__ init __() '呼び出しを行う特別な理由はありますか? – Homer

+1

前に '__init__'を呼び出していないと、' fields'属性は定義されません。 'fields'属性は' BaseForm'のinitメソッドで定義されています:https://github.com/django/django/blob/master/django/forms/forms.py#L95 –

関連する問題