Inline formsets Django

Asked

Viewed 18 times

0

Hello, I am until that experienced in Django but I am having an error that I am not able to solve, well the error is this, I have an inlineformset_factory and when I go to save it not saved and says that is_valid is false, I’ve done everything but the function does not work.

view py.

@login_required(login_url="/login/")
def cadastro_movimentacao_produtos(request):
    nivel = permissao(request)
    nome_empresa = consulta_nome_empresa(request)

    empresa = consulta_usuario(request)

    produtos = Produtos.objects.filter(empresa=empresa)
    
    ItensMovProdutosFormset = inlineformset_factory(MovimentacaoProdutos, ItensMovProdutos, extra=1, form=ItensMovProdutosForm)
 
    if request.method == 'POST':
    
        data_mov = request.POST['data_mov']
        
        form = MovimentacaoProdutosForm(request.user, request.POST)
        formset = ItensMovProdutosFormset(request.POST)
        print(formset.is_bound)
        if form.is_valid() and formset.is_valid():
            form.save()
            last_mov = MovimentacaoProdutos.objects.latest('id')

            for inline_form in formset:
                if inline_form.cleaned_data:
                    
                    produto_form = inline_form.save(commit=False)
                    produto_form.question = ItensMovProdutos
                    produto_form.save()

            messages.success(request, 'Movimentação de produtos cadastrado com sucesso!')

            user = request.user.id

            obj_mov = MovimentacaoProdutos.objects.filter(id=last_mov.id)

            obj_mov.update(usuario_id=user)

            return HttpResponseRedirect('/lista-movimentacao-produtos/')

        else:
            print(form.errors, 'Comum form')
            print(formset.errors, 'Formset')
            
    else:
        form = MovimentacaoProdutosForm(request.user)
        formset = ItensMovProdutosFormset()

    perm = permissao(request)
    if perm >= 2:
        return render(request, 'cadastros/cadastro-mov-produto.html', locals())
    else:        
        return render(request, 'verificacao/no-access.html', locals())

JS and HTML



    <script type="text/javascript">
        $(function() {
            $('.inlineform').formset({
                prefix: '{{ formset.prefix }}',
                addText: '<label id="mais" class="btn btn-success" style="color: white !important; ">Adicionar Produto <i  class="fas fa-plus"></i></label>',
                deleteText: '<label id="lixo" class="btn btn-danger" style="color: white !important; ">Deletar Produto <i class="fas fa-trash-alt"></i></label>',
            });
            $('.datetimeinput').datetimepicker();
            
        })
    </script>

<!-- language: lang-html -->

    {% for forms in formset %}
    <div class='inlineform'>
    <div class='card p-md-0'>
        <div class='card-header border-bottom p-md-4 ml-2'>
            <h2>Produto</h2>
        </div>
        <div class='card-body'>
            <div class='form-row'>
            {% for campo in forms.visible_fields %}

                <div class="form-group col-md-3 mb-0 table">

                        {% for hidden in forms.hidden_fields %}
                            {{ hidden }}
                        {% endfor %}
                            {{ campo.errors.as_ul }}
                            {{ campo|as_crispy_field }}
                        <hr>
                </div>


            {% endfor %}
            </div>
        </div>
    </div>
    </div>
    {% endfor %}

<!-- end snippet -->

Form

class ItensMovProdutosForm(forms.ModelForm):
    
    status = forms.ChoiceField(label='Status', required=False, choices=[
            (0, 'Ativo'),
            (1, 'Desativo'),
        ])
    
    motivos = forms.CharField(label='Motivo')
    class Meta:
        model = ItensMovProdutos

        fields = ['empresa', 'produto', 'qtde', 'vlr_unit', 'total', 'status', 'motivos']

        exclude = ['movimentacaoprodutos', 'usuario']

Model

class ItensMovProdutos(models.Model):

    empresa = models.ForeignKey("EmpresaFilial", on_delete=models.CASCADE, null=True)
    produto = models.ForeignKey("Produtos", on_delete=models.CASCADE, null=True)
    movimentacaoprodutos = models.ForeignKey("MovimentacaoProdutos", on_delete=models.CASCADE, null=True)
    usuario = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
    motivos = models.TextField(u'Motivos', max_length=70, null=True)    
    qtde = models.DecimalField(u'Quantidade', max_digits=8, decimal_places=2, null=True)
    vlr_unit = models.DecimalField(u'Valor Unitário', max_digits=8, decimal_places=2, null=True)
    total = models.DecimalField(u'Total', max_digits=8, decimal_places=2, null=True)
    status = models.IntegerField(u'Status', null=True)

    class Meta:
        ordering = ['produto']

    def __str__(self):
        return str(self.produto) 
  • If the formset validation is failing you should see what you have in formset.errors. So you can understand which validation failed... Remembering that formsets have metadata that are required to be valid, see here.

  • so the problem is that formset.errors is bringing an empty list

1 answer

0

Well after a lot of research I discovered the problem, and here’s the thing, the formset needs you to reference it as management_form so just add {{ formset.management_form }} before the loop of your formset.

{{ formset.management_form }} <--Desta forma-->
{% for forms in formset %}
<div class='inlineform'>
   <div class='card p-md-0'>
      <div class='card-header border-bottom p-md-4 ml-2'>
         <h2>Produto</h2>
      </div>
      <div class='card-body'>
         <div class='form-row'>
                    
            {% for campo in forms.visible_fields %}
                    
               <div class="form-group col-md-3 mb-0 table">
                    
                  {% for hidden in forms.hidden_fields %}
                      {{ hidden }}
                  {% endfor %}
                  {{ campo.errors.as_ul }}
                  {{ campo|as_crispy_field }}
                  <hr>
               </div>
                        
                    
              {% endfor %}
           </div>
       </div>
    </div>
 </div>

{% endfor %}

Browser other questions tagged

You are not signed in. Login or sign up in order to post.