@ilya_chch

Как сделать formset для нескольких объектов БД?

Есть модель, с которой внешним ключем связана еще одна модель.

class Obj(Model):
    some_field = CharField(...)

class ForeignObj(Model):
    obj = ForeignKey(Obj, related_name="foreign_obj")
    some_data = IntegerField()


На некотором этапе существуют объекты Obj, но не для всех существуют объекты ForeignObj.

Есть модельная форма для ForeignObj:
class ForeignObjForm(ModelForm):
    obj = ModelChoiceField(
        queryset=Obj.objects.all(),
        widget=forms.HiddenInput()
    )

    def __init__(self, *args, **kwargs):
        self.obj = kwargs.pop('obj')
        super(ForeignObjForm, self).__init__(*args, **kwargs)
        self.fields['obj '].initial = self.obj

    class Meta:
        model = ForeignObj
        fields = '__all__'


Для одного объекта все работает, что не вызывает вопросов.

Теперь допустим, есть несколько объектов Obj, для которых не существует ForeignObj.
Необходимо создать форму для пакетного создания объектов ForeignObj. Как реализовать такое?

Самое простое решение "в лоб":
в шаблоне руками перебрать весь QuerySet с объектами Obj и самому создать разметку, создаваемую FormSet, но мне кажется, что это не самый правильный вариант.

Варианты решения:
1) самому создать формы для каждого Obj и как-то (как?) их объединить и пакетно обработать.
2) передать в form_set_factory QuerySet объектов Obj, чтобы он перебрав его, создал сам все формы, передав в них поочередно каждый элемент QuerySet

Варианты решения - то, что пришло в голову, однако не могу придумать, как это сделать...
  • Вопрос задан
  • 235 просмотров
Решения вопроса 1
@ilya_chch Автор вопроса
Нашел решение, может кому будет полезно:
class ForeignObjFormSet:
    def get_form_kwargs(self, index):
        kwargs = super(ForeignObjFormSet, self).get_form_kwargs(index)
        kwargs['obj'] = self.form_kwargs['obj'][index]
        return kwargs

# Во вьюхе
def view(request):
    target_objects = Obj.objects.filter(foreign_obj__isnull=True)
    FormSet = formset_factory(forms.ForeignObjForm, formset=ForeignObjFormSet, extra=target_objects.count())
    form_set = FormSet(form_kwargs={'obj': list(target_objects)})
# ...
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы