Django:使用外键保存动态表单

时间:2016-01-17 11:45:02

标签: python django django-forms django-views

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

我有以下型号:

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有一个foriegn密钥到myinfo的2个表单?我做的更好吗?提前谢谢你,

1 个答案:

答案 0 :(得分: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()。 formset是表单的集合,而不是字段的集合。

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