在 DJANGO 中保存表单集

Save Formset in DJANGO

我有一个来自模型的表单集,但是当我尝试保存多个表单集时出现错误:

KeyError at /auditoria/auditoria_tab/ 'id_control'

我的看法:

@staff_member_required
def AuditoriaView(request):
   class RequiredFormset(BaseFormSet):
      def __init__(self,*args,**kwargs):
         super(RequiredFormset,self).__init__(*args,**kwargs)
         for form in self.forms:
            form.empty_permitted =  False

   auditoriaFormset = formset_factory(AuditoriaForm,max_num=31,formset=RequiredFormset)

   if request.method == 'POST':
      usuario = request.user
      accion = 'Registro nuevo Detalle de Auditoria'
      formset  = auditoriaFormset(request.POST)
      for form in formset.forms:
         if formset.is_valid():
            obj = form.save(commit=False)
            #obj.id_control = control
            obj.auditor = request.user
            obj.save()
   else:
      formset = auditoriaFormset()

   return render_to_response('audit_auditoria.html',
                              {'formset':formset},
                              context_instance=RequestContext(request))

我的表格:

class AuditoriaForm(forms.ModelForm):
   id_control = forms.ModelChoiceField(queryset=Control.objects.all().order_by('nombre'),\
                                       required=True,label='Control', widget=forms.Select(attrs={'class':'form-control'}))
   id_analista = UserModelNameChoiceField(queryset=User.objects.filter(is_staff=False),\
                                          required = True, label='Analista', widget=forms.Select(attrs={'class':'form-control'}))
   fecha = forms.DateField(widget=DateInputCustom())
   id_tipoerror = forms.ModelChoiceField(queryset=TipoError.objects.all(),required=True, label='Tipo Falla', widget=forms.Select(attrs={'class':'form-control'}))
   id_sharepoint = forms.IntegerField(label='Sharepoint', widget=forms.NumberInput(attrs={'class':'form-control','style': 'width:80px'}))
   id_estado = forms.ModelChoiceField(queryset=Estado.objects.all(),required=True, label='Estado', widget=forms.Select(attrs={'class':'form-control'}))
   observaciones = forms.CharField(widget=forms.Textarea(attrs={'rows':5,'cols':30}))

   class Meta:
      model = DetalleAuditoria
      exclude = ('auditor',)

   def __init__(self,*args,**kwargs):
      super(AuditoriaForm,self).__init__(*args,**kwargs)
      self.helper = FormHelper(self)

   def clean(self):
      cleaned_data = super(AuditoriaForm,self).clean()
      idc = cleaned_data['id_control']
      fechac = cleaned_data['fecha']

      try:
         DetalleAuditoria.objects.get(id_control = idc,fecha = fechac )
         raise forms.ValidationError('Esta Incidencia ya ha sido registrada')
      except DetalleAuditoria.DoesNotExist:
         pass

      return cleaned_data

模板:

<form id="form_audit" class="form" method="post" action="/auditoria/auditoria_tab/">
            <table class="table table-responsive table-condensed table-bordered">
              {{ formset.management_form }}
                {% for form in formset.forms %}
               <thead>
                <th class="info"colspan="6">
                  <label >{{ form.id_control.label|capfirst }} </label>
                  {{ form.id_control }}
                </th>
               </thead>
               <thead>
               <th>{{ form.id_analista.label|capfirst }}</th>
               <th>{{ form.id_sharepoint.label|capfirst }}</th>
               <th>{{ form.fecha.label|capfirst }}</th>
               <th>{{ form.id_tipoerror.label|capfirst }}</th>
               <th>{{ form.id_estado.label|capfirst }}</th>
               <th>{{ form.observaciones.label|capfirst }}</th>
              <thead>
              <tbody>
              <tr class="{% cycle row1,row2 %} formset_row">
               <td>{{ form.id_analista }}</td>
               <td>{{ form.id_sharepoint }}</td>
               <td>{{ form.fecha }}</td>
               <td>{{ form.id_tipoerror }}</td>
               <td>{{ form.id_estado }}</td>
               <td>{{ form.observaciones }}</td>
              </tr>
               {% endfor %}
              </tbody>
            </table>
              <input type="submit" class="btn btn-info" value="Registrar">
            </form>

{% block extra_js %}
<script src="{{STATIC_URL|default:"/static/"}}admin/js/jquery.formset.js"></script>

<script type="text/javascript">

   function renewDatePickers() {
    $('.datepicker').datepicker('destroy');
    $('.datepicker').datepicker({
        format: "yyyy-mm-dd",
        startDate: "2014-01-01",
        endDate: "2020-01-01",
        autoclose: true
    });
   }

   $(renewDatePickers);

    $('.formset_row').formset({
        addText: 'Agregar Detalle Auditoria',
        deleteText: 'Eliminar',
        prefix: '{{ formset.prefix }}',
        added: renewDatePickers
    });

</script>

{% endblock extra_js %}

当我想保存数据时,如何在其他表单集中使用第一个表单集中的字段 ID_CONTROL。

我不确定我是否以正确的方式使用了表单集?

任何建议

提前致谢

更新: 我在 "clean" 函数中收到错误。当视图尝试保存第二个表单集时,错误出现在以下行中:

  idc = cleaned_data['id_control']

在错误页面中我可以看到 post 并且我可以看到第一个表单集的 id_control 值,但是对于第二个表单集我看到了除 id_control 之外的所有字段.

在我看来,以这种方式将相同的控件 ID 放入下一个表单中是没有意义的。 无论如何,为了解决您的要求,这应该是有效的(具有不同的 "fecha" 值形式):

   id_control=None
   if request.method == 'POST':
      usuario = request.user
      accion = 'Registro nuevo Detalle de Auditoria'
      formset  = auditoriaFormset(request.POST)

      for counter, form in enumerate(formset.forms):
         if formset.is_valid():
            obj = form.save(commit=False)
            if counter>0:
                obj.id_control = id_control
            obj.auditor = request.user
            obj.save()
            if counter==0:
                id_control=obj.id_control
   else:
      formset = auditoriaFormset()