【问题标题】:Django: saving dynamic forms with foreign keyDjango:使用外键保存动态表单
【发布时间】:2016-04-22 15:11:21
【问题描述】:

我想就我的问题寻求帮助和指导。

我有以下型号:

class myinfo(models.Model):
    name = models.CharField(max_length=30, null=True)


class mynumbers(models.Model):
    fkey = models.ForeignKey("myinfo")
    Job_Position = models.CharField(max_length=30, null=True)

mynumbers 模型是通过django-dynamic-formset 动态生成的。

我的表格

class info(ModelForm):
    name= forms.CharField( max_length=20)

    class Meta:
        model = APPLICANT_DATA
        fields = ('name',)

class numbers(ModelForm):
    number = forms.CharField( max_length=20)

    class Meta:
        model = APPLICANT_DATA
        fields = ('number',)

如果您想保存动态表单字段,您必须在视图中执行此操作

for field in formset:
    field.save()

我的看法:

def index(request):

    aformset = formset_factory(numbers)
    formset = aformset(request.POST)
    form = info(request.POST)

    if request.method == 'POST':

        if form.is_valid():
            if formset.is_valid():
                for field in formset:
                    formset.save()

                form.save()

但是当我的动态生成的字段有一个外键(mynumbers)时,问题就开始了,这会引发错误must be a myinfo instance。如何保存mynumbers 具有myinfo 的外键的2 个表单?有没有比我做的更好的方法?提前谢谢你,

【问题讨论】:

    标签: python django django-forms django-views


    【解决方案1】:

    这是使用inlineformset_factory 的地方。这允许您拥有一个父模型和多个子模型(通过外键与父模型相关)并将它们保存在一起。有许多参数可以传递给 inlineformset_factory 以自定义行为(例如允许的内联表单的最小和最大数量,用户是否可以删除内联表单等),但关键如下所示。

    # views.py
    
    from django.forms.models import inlineformset_factory
    from my_app.forms import numbers as NumberForm
    from my_app.forms import info as InfoForm
    from my_app import models
    
    myFormset = inlineformset_factory(models.myinfo,
        models.mynumbers,
        form=NumberForm
    )
    
    def index(request):
        if request.POST:
            form = InfoForm(request.POST)
            if form.is_valid():
                info = form.save(commit=False)
                formset = myFormset(request.POST, instance=info)
                if formset.is_valid():
                    info.save()
                    formset.save()
                    return HttpResponse('saved successfully')
        else:
            form = InfoForm()
            formset = myFormset(instance=models.myinfo())
        return render_to_response("recipes/submit.html", {
                                                        "form": form,
                                                        "formset":formset,    
                                                        }, 
                                context_instance=RequestContext(request))
    

    请注意:在您的问题中,您输入了for field in formset: formset.save()。表单集是表单的集合,而不是字段的集合。

    Formsets 可能很棘手,需要使用不属于常规表单的其他模板组件正确呈现模板(例如 management_form 变量,它允许 Django 正确处理已添加/删除/移动/更改的内容) .绝对值得做一些教程,以了解最佳实践,这样您就不会因自定义实现而陷入故障排除陷阱。 我建议 this post from Charles Leifer 作为熟悉基础知识的好入口。

    【讨论】:

    • 感谢您的回复,每当我尝试保存formset 时,它总是会报错说没有formset.save(),但是当我循环它时它会保存,无论如何,我会尝试谢谢你的回答。
    • 确保 myFormset = inlineformset_factory(models.myinfo, models.mynumbers, form=NumberForm ) 在您的视图之外;除了在视图中使用 formset = myFormset(instance=...) 实例化您的表单集之外,这是必需的。
    • 效果很好,谢谢,inlineformset_factory 的效果如何?
    • inlineformset_factory 是一个构造函数,用于为特定模型(分组为表单集)创建任意数量的表单,这些表单都具有相同父模型的外键。使用 inlineformset_factory,您可以创建一个表单(用于 myinfo)和匹配的表单集(用于 mynumbers),用户可以在其中编辑单个 myinfo 实例以及您在规则中设置的任意数量的 mynumbers 实例。表单集很棘手,但一旦你掌握了它,它们就会非常强大。我建议查看诸如此类的一些教程 - charlesleifer.com/blog/djangos-inlineformsetfactory-and-you
    猜你喜欢
    • 2013-10-11
    • 1970-01-01
    • 2014-09-07
    • 2023-03-22
    • 1970-01-01
    • 2012-09-20
    • 1970-01-01
    • 2011-02-24
    • 2012-03-14
    相关资源
    最近更新 更多