尝试以 django 嵌套内联表单集的嵌套形式设置用户字段 - 失败

问题描述

我遵循了这个:https://www.yergler.net/2009/09/27/nested-formsets-with-django/ 和这个:django inline formsets with a complex model for the nested form,总的来说我的代码运行良好。


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,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,formset=BasenestedTransactionFormset,extra=0)

我的模板有一个表格,显示导入数据表单集...用户选择帐户,表格显示从该帐户导入的所有数据。对于这些行表单中的每一个,下面都有一个隐藏行...用户单击一个按钮以显示该隐藏行。隐藏行显示嵌套分类表单集。

如果在模板中包含 user_username 字段并允许它成为模板中嵌套表单集的一部分,我可以相应地在 html 表单中设置,并且表单集保存没有问题。

但是:我希望能够从模板中排除 user_username 字段,并让我的视图或 BasenestedTransactionFormset 类下的某些其他方法将 user_username 字段的值设置为 request.user 值对于当时登录的任何人.

我尝试覆盖 clean 方法,但由于表单未验证,cleaned_data 返回错误;该字段是必需的。我似乎想不出一个好的方法来做到这一点。

如果这是一个普通的表单集,做起来并不难。我只是通过修改 POST 返回的内容来设置该字段。我从来没有使用过嵌套的内联表单集,字段名称中的前缀和索引已经让我知道了。我已经在这里待了几天,但似乎无处可去。

我也在考虑从分类模型中删除该字段,因为它已经绑定到链接登录用户的 ImportData 模型。我只是想我可能会在某个时候再次遇到这个问题,所以也许很好解决

提前致谢。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)