modelformset_factory不承认额外参数

时间:2012-10-18 08:50:45

标签: django django-forms

Django:1.4.1

型号:

class Hoja(models.Model):
    nombre = models.CharField(max_length=200) # requerido

class Linea(models.Model):
    hoja = models.ForeignKey(Hoja) # requerido
    nombre = models.CharField(max_length=200) # requerido
    padre = models.ForeignKey('self', null=True, blank=True, related_name='hijo')

查看:

lineas = Linea.objects.filter(hoja=alt).order_by('id')
LineaHojaSet = modelformset_factory(Linea, can_delete=True, extra=1 if request.POST.has_key('siguiente') else 0)
formset = LineaHojaSet(request.POST or None, queryset=lineas)
if request.method=='POST':
    # process formset
return render_to_response('template.html', {'formset':formset}, context_instance=RequestContext(request))

模板:

<table>
    <thead>
        <tr><th>Nombre</th><th>Borrar</th></tr>
    </thead>
    <tbody>
        {% for fs in formset %}
        <tr>
            <td>{{ fs.nombre }}</td>
            <td>{{ fs.id }}</td>
        </tr>
        {% endfor %}
    </tbody>
</table>
<input type="submit" name="siguiente" value="Añadir siguiente" />

当我提交“siguiente”按钮时,我可以看到,formset正在获得正确的额外字段1,但在网页中,显示的唯一行是数据库。这是一个错误,或者我做错了什么?

1 个答案:

答案 0 :(得分:2)

Formset工厂通过管理表单中的max_num(或数据)中的extraform-TOTAL_FORMS参数或request.POST参数查找表单数量。

在您的情况下,request.POST['form-TOTAL_FORMS']的号码不包含额外的表格。因此,在创建formset时不会添加额外的表单。

一种解决方案是在满足条件时将此数字增加1。 e.g。

data = None
if request.POST:
    data = request.POST.copy() #required as request.POST is immutable
if request.POST.has_key('siguiente'):
   data['form-TOTAL_FORMS'] = int(data['form-TOTAL_FORMS']) + 1

#now use data instead of request.POST
formset = LineaHojaSet(data, queryset=lineas)
....

但是,以这种方式操作formset存在一些缺点。验证formset时,如果有任何必填字段,额外的表单将显示错误。

更好的解决方案是在使用一个额外的表单和查询集传递模板之前再次创建formset。最有可能的是,当formset有效时,您将保存任何新对象,这些对象将由queryset添加。因此,您的页面将显示新添加的对象和一个额外的表单。

lineas = Linea.objects.filter(hoja=alt).order_by('id')
LineaHojaSet = modelformset_factory(Linea, can_delete=True,)
formset = LineaHojaSet(request.POST or None, queryset=lineas)
if request.method=='POST':
    # process formset
    if formset.is_valid:
       #saved and done with formset.
       if request.POST.has_key('siguiente'):
           LineaHojaSet = modelformset_factory(Linea, can_delete=True, extra=1)
           formset = LineaHojaSet(queryset=lineas)
           ...
return render_to_response('template.html', {'formset':formset}, context_instance=RequestContext(request))