Django, установите исходные данные для formset с ManyToMany - PullRequest
4 голосов
/ 07 марта 2011

Мне нужно установить начальные данные на formset с полем ManyToMany.

Обычно я делаю так, когда нет Поле ManyToMany в формах моего набора:

PersonFormSet = forms.formsets.formset_factory(NickName, can_delete=True)
init_data = [{'name':'Vasya pupkin','nick':'Vasya'}, 
             {'name':'Vasyapupkin','nick':'Petya'}]

nick_formset = PersonFormSet(initial=init_data)

Но теперь мне нужно установить начальные данные поля ManyToMany и попробовать что-то вроде этого:

NickNameFormSet = forms.formsets.formset_factory(NickName, can_delete=True)
init_data = [{'name': 'Vasya Pupkin',
              'nick': {'Vasya':'selected',
                       'Petya':'notselected'}}]

nick_formset = NickNameFormSet(initial=init_data)

Но это не работает.

Как передать начальные данные в Formset, чтобы он отображал мой виджет следующим образом:

<select multiple="multiple" name="person_set-0-nickname" id="id_person_set-0-nickname">
    <option value="1" selected="selected">Vasya</option>
    <option value="2">Petya</option>
</select>

Примечание : я использую только формы и наборы форм Django. Там нет моделей Django. Я действительно могу определить это, но оно пустое, я использую NoSQL.

Ответы [ 3 ]

1 голос
/ 19 декабря 2011

Вы должны предоставить список pk в качестве исходных данных для вашего отношения ManyToMany вместо dict.

Взгляните на эту ветку , она может вам помочь.

0 голосов
/ 13 декабря 2018

Как это:

class CustomFormSet(BaseInlineFormSet):
    def __init__(self, *args, **kwargs):
        kwargs['initial'] = [
            {'foo_id': 1}
        ]
        super(CustomFormSet, self).__init__(*args, **kwargs)

foo_id зависит от значения, которое вы выбираете для какого поля в отношении модели

Необходимо также изменить метод has_changed в классе формы, чтобы он знал, что начальные значения «изменены», чтобы их учитывать при сохранении:

class CustomForm(forms.ModelForm):
    def has_changed(self):
        """
        Overriding this, as the initial data passed to the form does not get noticed,
        and so does not get saved, unless it actually changes
        """
        changed_data = super(starnpc_class, self).has_changed()
        return bool(self.initial or changed_data)
0 голосов
/ 16 декабря 2016

Вы можете использовать функцию __init__ для предварительного заполнения начальных данных.

Вот что я использовал для аналогичной проблемы:

class MyUpdateForm(forms.ModelForm):

    def __init__(self, *args, **kwargs):
        super(MyUpdateForm, self).__init__(*args, **kwargs)
        self.initial['real_supplements'] = [s.pk for s in list(self.instance.plan_supplements.all())]

Вместо использования self.instance.plan_supplements.all() в моем примере вы можете указать любой набор запросов.

...