2015-06-09 2 views
4

В Django 1.8, то ChoiceField «s choices аргумента может принимать вызываемый:Как можно выбрать ChoiceField.choices, какие варианты возврата?

def get_choices(): 
    return [(1, "one"), (2, "two")] 

class MyForm(forms.Form): 
    my_choice_field = forms.ChoiceField(choices=get_choices) 

В приведенном выше примере, get_choices() всегда возвращает тот же самый выбор. Тем не менее, возможность назначить вызываемый choices не имеет большого смысла, если только вызывающий код не знает что-то вроде, скажем, идентификатора объекта, каждый раз, когда он вызывается. Как я могу передать ему такую ​​вещь?

ответ

5

Вы не можете сделать это в декларации формы, потому что the CallableChoiceIterator calls the function without argumentsthat he gets from here. Выполнение в __init__ Метод формы проще, чем создание собственного ChoiceField. Вот что я предлагаю:

class MyForm(forms.Form): 
    my_choice_field = forms.ChoiceField(choices=()) 

    def __init__(self, *args, **kwargs): 
     # Let's pass the object id as a form kwarg 
     self.object_id = kwargs.pop('object_id') 

     # django metaclass magic to construct fields 
     super().__init__(*args, **kwargs) 

     # Now you can get your choices based on that object id    
     self.fields['my_choice_field'].choices = your_get_choices_function(self.object_id) 

Это предполагает, что у вас есть класс, основанный вид, который выглядит, что есть метод, как это:

class MyFormView(FormView): 
    # ... 

    def get_form_kwargs(self): 
     kwargs = super().get_form_kwargs() 
     kwargs['object_id'] = 'YOUR_OBJECT_ID_HERE' 
     return kwargs 

    # ... 

PS: вызов функции супер() предусматривающий вы используя python 3

+0

Ваш метод поставки 'get_choices()' не определен нигде. – jnns

+0

@jnns Определяется в вопросе – Anass

+0

Да, вы правы. Но я нахожу очень запутанным и ненужным иметь эту функцию там, если она никогда не вызывается и фактически перезаписывается в '__init__'. – jnns

Смежные вопросы