简体   繁体   中英

Problem validating modelformset_factory in Django

I have a problem trying to validate a modelform and, after various tests, I think the problem is with the html template in how the information is displayed.

I have 2 models:

models.py:

class bdAccesorios(models.Model):
    fdClienteAcc=models.CharField(max_length=35)
    fdProveedorAcc=models.CharField(max_length=60)
    fdSkuAcc=models.CharField(max_length=30)
    fdNombreAcc=models.CharField(max_length=60)
    fdCostoAcc=models.DecimalField(max_digits=8, decimal_places=2)
    fdUnidadAcc=models.CharField(max_length=30)
    fdExistenciaAcc=models.IntegerField()
    fdAuxAcc=models.CharField(max_length=60, default="0")

class bdComponentes(models.Model):
    fdGrupoComp=models.CharField(max_length=30)
    fdNombreComp=models.CharField(max_length=60)
    fdSkuComp=models.CharField(max_length=30)
    fdExistenciaComp=models.DecimalField(max_digits=8, decimal_places=2)
    fdDesgloseComp=models.ManyToManyField(bdAccesorios, through="bdComponentesDesglose")
    fdPertenenciaComp=models.ForeignKey(bdUsuariosAux , on_delete=models.CASCADE)
    fdAuxComp=models.CharField(max_length=60, default="0")

and establish a many to many relationship through a third model to

class bdComponentesDesglose(models.Model):
    fdAccesorioCompDes=models.ForeignKey(bdAccesorios, on_delete=models.CASCADE)
    fdComponenteCompDes=models.ForeignKey(bdComponentes, on_delete=models.CASCADE)
    fdCantidadCompDes=models.IntegerField(default=1)
    fdPrecioTotalAcc=models.DecimalField(max_digits=8, decimal_places=2, blank="true", 
    editable="false")

To update bdComponentes I combine two forms

forms.py:

class fmComponente(ModelForm):
    class Meta:
        model=bdComponentes
        fields='__all__'
        exclude = ('fdAuxComp', 'fdDesgloseComp')
        labels = {
            'fdGrupoComp': 'Grupo',
            'fdSkuComp': 'SKU',
            'fdNombreComp': 'Nombre',
            'fdPertenenciaComp': 'Cliente',
            'fdExistenciaComp': 'Existencia',
        }

class fmComponenteDes(ModelForm):
    class Meta:
        model=bdComponentesDesglose
        fields='__all__'
        exclude = ('fdComponenteCompDes','fdPrecioTotalAcc',)
        labels = {
            'fdAccesorioCompDes': 'Accesorio',
            'fdCantidadCompDes': 'Cantidad',
        }

Then I make a view to update the model

views.py:

def vwComponenteModificar(request,IDComp):
    vrModificarComp = bdComponentes.objects.get(id=IDComp)
    vrModificarCompDes = bdComponentesDesglose.objects.filter(fdComponenteCompDes__fdNombreComp=vrModificarComp.fdNombreComp)
    vrComponenteForm=fmComponente(instance=vrModificarComp)
    vrComponenteDesModelForm = modelformset_factory(bdComponentesDesglose, extra=0, exclude = ('fdComponenteCompDes','fdPrecioTotalAcc',))
    vrComponenteDesForm=vrComponenteDesModelForm(queryset=vrModificarCompDes)
    if request.method == "POST":
        vrComponenteForm = fmComponente(request.POST, instance=vrModificarComp)
        vrComponenteDesForm=vrComponenteDesModelForm(request.POST)
        if vrComponenteForm.is_valid() and vrComponenteDesForm.is_valid(): ###Here is the problem
            vrComponenteForm.save()
            for lpCompDes in vrComponenteDesForm:
                lpCompDes.save()
            return redirect('/')
    return render(request,"Myapp/ComponentesCrear.html",{
                'dtCrearComp': vrComponenteForm,
                'dtCrearCompDes': vrComponenteDesForm
    })

My problem is in my template the view, previously mention, works perfectly when my template is like this

template:

  <form action="" method="post">
    {% csrf_token %}
    <table>
      {{ dtCrearComp.management_form}}
      {{dtCrearComp}}
        <div class="">
           {{dtCrearCompDes.management_form}}
           {{dtCrearCompDes}}
        </div>
    </table>
    <input type="submit" name="Terminar" value="Terminar">
  </form>

But i need to change my template to this, because I added some javascript logic to add buttons that add formset fields dynamically

  <form class="" method="POST" action="">
      {% csrf_token %}
      <div class="">
        {{dtCrearComp.management_form}}
        <table>
          {{dtCrearComp}}
        <table>
      </div>

    {{dtCrearCompDes.management_form}}
    {% for lpCrearCompDes in dtCrearCompDes %}
    <div class="row form-row spacer">
              <label>{{lpCrearCompDes.fdAccesorioCompDes.label}}</label>
              {{lpCrearCompDes.fdAccesorioCompDes}}
              <label>{{lpCrearCompDes.fdCantidadCompDes.label}}</label>
              {{lpCrearCompDes.fdCantidadCompDes}}
              <button class="btn btn-success add-form-row">+</button>
    </div>
    {% endfor %}

And this new template gives me in my view a vrComponenteDesForm.is_valid()=False

After some trial and error, I found the solution by changing the template to this:

{{dtCrearCompDes.management_form}}
{% for lpCrearCompDes in dtCrearCompDes %}
<div class="row form-row spacer">
      {{lpCrearCompDes.as_p}}
          <button class="btn btn-success add-form-row">+</button>
</div>
{% endfor %}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM