4

姜戈: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”按钮时,我可以看到表单集获得了正确的额外字段 1,但在网页中,唯一显示的行是数据库行。这是一个错误,还是我做错了什么?

4

1 回答 1

2

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

在您的情况下,request.POST['form-TOTAL_FORMS']具有不包括额外形式的数字。所以当你创建表单集时它不会添加额外的表单。

一种解决方案是在满足您的条件时将此数字加一。例如

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 有效时,您将保存任何新对象,这些对象将由 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))
于 2012-10-18T09:21:46.123 回答