Попытка установить пользовательское поле во вложенной форме вложенного встроенного набора форм django - терпит неудачу

Я следовал этому: https://www.yergler.net/2009/09/27/nested-formsets-with-django/ и это: встроенные формы django со сложной моделью для вложенной формы, и в целом мой код отлично работает.


class Account(models.Model):
    user_username = models.ForeignKey(User, on_delete=models.CASCADE)
    account_name = models.CharField(max_length=30)
    
class Classification(models.Model):
    user_username=models.ForeignKey(User, on_delete=models.CASCADE)
    data_id=models.ForeignKey(ImportData, on_delete=models.CASCADE)
    
class ImportData(models.Model):
    user_username = models.ForeignKey(User, on_delete=models.CASCADE)
    data_id = models.UUIDField(
        primary_key=True, default=uuid.uuid4, editable=False)

ClassificationFormset = inlineformset_factory(ImportData, Classification, exclude=('user_username',), extra=1)

# below is just what came from the nested formset links above: pasted here for easy reference.

class BaseNestedTransactionFormset(BaseInlineFormSet):
    def add_fields(self, form, index):
        # allow the super class to create the fields as usual
        super(BaseNestedTransactionFormset, self).add_fields(form, index)

        try:
            instance = self.get_queryset()[index]
            pk_value = instance.pk
        except IndexError:
            instance=None
            pk_value = hash(form.prefix)

        transaction_data = None

        if (self.data):
            transaction_data = self.data;

        # store the formset in the .nested property
        form.nested = [
            CategoryFormset(data=transaction_data,
                            instance = instance,
                            prefix = 'CAT_%s' % pk_value)]


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

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


    def save_new(self, form, commit=True):
        """Saves and returns a new model instance for the given form."""

        instance = super(BaseNestedTransactionFormset, self).save_new(form, commit=commit)

        # update the form’s instance reference
        form.instance = instance

        # update the instance reference on nested forms
        for nested in form.nested:
            nested.instance = instance

            # iterate over the cleaned_data of the nested formset and update the foreignkey reference
            for cd in nested.cleaned_data:
                cd[nested.fk.name] = instance

        return instance

    def save_all(self, commit=True):
        """Save all formsets and along with their nested formsets."""

        # Save without committing (so self.saved_forms is populated)
        # — We need self.saved_forms so we can go back and access
        #    the nested formsets
        objects = self.save(commit=False)

        # Save each instance if commit=True
        if commit:
            for o in objects:
                o.save()

        # save many to many fields if needed
        if not commit:
            self.save_m2m()

        # save the nested formsets
        for form in set(self.initial_forms + self.saved_forms):
            # if self.should_delete(form): continue

            for nested in form.nested:
                nested.save(commit=commit)

ImportTransactionFormset = inlineformset_factory(Account, ImportData, exclude=('user_username',), formset=BaseNestedTransactionFormset, extra=0)

В моем шаблоне есть таблица, в которой отображается набор форм импорта данных... пользователь выбирает учетную запись, и в таблице отображаются все импортированные данные из этой учетной записи. Для каждой из этих форм строк внизу есть скрытая строка... пользователь нажимает кнопку, чтобы отобразить эту скрытую строку. Скрытая строка отображает вложенный набор форм классификации.

Если включить поле user_username в шаблон и разрешить ему быть частью вложенного набора форм в шаблоне, я могу установить его соответственно в форме html, и наборы форм не сохранятся.

Однако: я хочу иметь возможность исключить поле user_username из шаблона, а мое представление или какой-либо другой метод в классе BaseNestedTransactionFormset установить значение поля user_username в значение request.user для всех, кто вошел в систему в это время.

Я попытался переопределить метод очистки, но clean_data выдает ошибку, потому что форма не проходит проверку; поле обязательно. Кажется, я не могу придумать хороший способ сделать это.

Если бы это был обычный набор форм, это было бы не так сложно сделать. Я бы просто установил поле, изменив то, что возвращается от POST. Я никогда не работал с вложенными встроенными формами, и меня достали префиксы и индексы в именах полей. Я был в этом в течение нескольких дней и, похоже, никуда не денется.

Я также подумываю просто избавиться от этого поля из модели классификации, поскольку оно уже привязано к модели ImportData, которая независимо связана с вошедшим в систему пользователем. Я просто думаю, что могу снова столкнуться с этим в какой-то момент, так что, может быть, хорошо решить.

Заранее спасибо.


person Chef Codev    schedule 21.03.2021    source источник