Динамический выбор для Django SelectMultiple Widget - PullRequest
4 голосов
/ 12 апреля 2010

Я создаю форму (не modelForm), где я хотел бы использовать виджет SelectMultiple для отображения вариантов выбора на основе запроса, выполненного во время инициализации формы.

Я могу придумать несколько способов сделать это, но я не совсем уверен, как правильно это сделать. Я вижу разные варианты.

Я получаю «варианты», которые я должен передать виджету в форме init , но я не уверен, как мне их передать.

class NavigatorExportForm(forms.Form):

def __init__(self,user, app_id, *args,**kwargs):
    super (NavigatorExportForm,self ).__init__(*args,**kwargs) # populates the form
    language_choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list('language', flat=True)

languages = forms.CharField(max_length=2, widget=forms.SelectMultiple(choices=???language_choices))

Ответы [ 2 ]

6 голосов
/ 13 апреля 2010

Почему бы не использовать ModelMultipleChoiceField вместо этого?

Вы можете сделать это просто:

class NavigatorExportForm(forms.Form):
    languages = forms.ModelMultipleChoiceField(queryset=Language.objects.all())

    def __init__(self, app_id, *args, **kwargs):
        super(NavigatorExportForm, self).__init__(*args, **kwargs)
        # Dynamically refine the queryset for the field
        self.fields['languages'].queryset = Navigator.admin_objects.get(id=app_id).languages.all()

Таким образом, вы не только ограничивает выбор, доступный в виджете, но и в поле (что дает вам проверку данных).

При использовании этого метода отображаемая строка в виджете будет результатом метода __unicode__ объекта Language. Если это не то, что вам нужно, вы можете написать следующее настраиваемое поле, как описано в ModelChoiceField reference :

class LanguageMultipleChoiceField(forms.ModelMultipleChoiceField):
    def label_from_instance(self, obj):
        return obj.language_code # for example, depending on your model

и используйте этот класс вместо ModelMultipleChoiceField в вашей форме.

0 голосов
/ 12 апреля 2010
def __init__(self,user, app_id, *args,**kwargs):
super (NavigatorExportForm,self ).__init__(*args,**kwargs)
self.fields['languages'].widget.choices = Navigator.admin_objects.get(id=app_id).languages.all().values_list('language', flat=True)

, кажется, делает свое дело, но даже не указывая max_length, виджет отображает только первую букву выбора ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...