formset встроенных formsets в django 1.3+ - PullRequest
0 голосов
/ 04 октября 2011

У меня есть модель товара и модель цены.Ценовая модель имеет FK для модели продукта.Может быть несколько цен (в зависимости от количества проданных единиц).До django 1.2.5 http://yergler.net/blog/2009/09/27/nested-formsets-with-django/ эта проблема была бы решена.Но, как указано http://www.mail-archive.com/django-users@googlegroups.com/msg124195.html, это больше не работает.

Конечный желаемый результат: следующая форма для редактирования и добавления данных.

Продукт Один - Цена Один, Количество - Цена Два, Количество Продукт Два - Цена Один, Количество Продукт Три - Цена Один, Количество - Цена Два, Количество - Цена Три, Количество

Воспроизводится дляясность:

В исходном коде Натана форма набора самого низкого уровня создается следующим образом:

TenantFormset(data=self.data,
              instance=instance,
              prefix='TENANTS_%s' % pk_value)

, где instance - это экземпляр Building, «родительский» или контейнер для арендаторов, а self -экземпляр

class BaseBuildingFormset(BaseInlineFormSet)

, который создается следующим образом:

BuildingFormset = inlineformset_factory(models.Block,
                                        models.Building,
                                        formset=BaseBuildingFormset,
                                        extra=1)

Чтобы обойти это, я перестал передавать self.data, что привело к тому, что формы в нижнем слое всегда имеют is_bound= Ложь, даже после рендеринга и отправки обратно в представление.Следовательно, проверка всегда заканчивается неудачей, и объекты, которые представляют формы, не могут быть обновлены.Я воспроизвел поведение, используя код из поста Натана в блоге, поэтому кажется, что этот подход к вложению наборов форм больше не действителен, или код требует настройки для работы с 1.3.

До Django 1.2.5, код Натана работает отлично.Однако в 1.3, если self.data передается в TenantFormset, он оказывается пустым, и возникает ошибка ValidationError, поскольку информация ManagementForm не была предоставлена.
Это предполагаемое следствие # 11418, AFAICT.

У кого-нибудь есть другие идеи о том, как это можно сделать?

Приветствия,

(Извините за отсутствие подробных примеров кода - пост Натана намного яснее, чем мой код, поэтому я рекомендую вам взглянуть на это.)

Общее примечание: кажется, что существует путаница в том, как это сделать, что показано в ответах здесь http://www.reddit.com/r/django/comments/hwyto/is_there_a_way_to_do_nested_formsets_in_django/

Ответы [ 3 ]

2 голосов
/ 21 февраля 2013

Как говорит django docs, необходимо передать данные = Нет, если форма не связана:

data = None
if self.data:
    data = self.data
form.nested = [ModelXYFormset(data=data, instance = instance, prefix = 'opt%s' % pk_value)]
0 голосов
/ 06 декабря 2011

Вот обходной путь, который, кажется, работает для получения форм sub-sub для проверки.

В BaseBuildingFormset:

def is_valid(self):
    result = super(BaseProtocolEventFormSet, self).is_valid()

    for form in self.forms:
        if hasattr(form, 'nested'):
            for n in form.nested:
                n.data = form.data
                if form.is_bound:
                    n.is_bound = True
                for nform in n:
                    nform.data = form.data
                    if form.is_bound:
                        nform.is_bound = True
                # make sure each nested formset is valid as well
                result = result and n.is_valid()
    return result

Данные для каждой формы и формыдолжно быть одинаковым (полные данные POST).Здесь мы вручную устанавливаем это для форм, которые не получают его.Мы также можем видеть, что в классе BaseForm is_bound просто проверяет, что форма имеет данные или файлы, поэтому, как только у формы есть данные, мы устанавливаем для этого значение true.

0 голосов
/ 04 октября 2011

Я сейчас пытаюсь сделать то же самое. Я реализовал то же решение из кода Натана, но столкнулся с проблемой ValidationError. В нашем Django 1.3 обновлено, как работают наборы форм, как показано здесь . Так что для моего кода,

TenantFormset(data=self.data, instance=instance, prefix='TENANTS_%s' % pk_value)

становится

TenantFormset(instance=instance, prefix='TENANTS_%s' % pk_value)

Но я все еще получаю бланк.

...