Você está na página 1de 5

11/03/2023, 07:46 Formulários dinâmicos com inlineformset_factory em uma aplicação Django // Felipe Frizzo

Felipe Frizzo

Formulários dinâmicos com


inlineformset_factory em uma aplicação
Django
2016-02-14 • Django > Python > Inline > Forms • Comments

Neste post iremos abordar de forma simples como utilizar o inlineformset_factory no


Django.

Modelo e Formulário

De maneira mais basica faremos uma lista de pedidos, onde poderemos adicionar um ou mais
produtos por pedido. Teriamos um modelo e um formulário como o exemplo abaixo.

# models.py
from django.db import models

class Order(models.Model):
client = models.CharField()
date = models.DateField(auto_now_add=True)

class ItemOrder(models.Model):
order = models.ForeignKey('Order')
product = models.CharField()
quantity = models.PositiveIntegerField()
price = models.DecimalField(max_digits=20, decimal_places=2)

# forms.py
from django import forms
from cadastro.models import Order, ItemOrder

class OrderForms(forms.ModelForm):
class Meta:
model = Order
exclude = ['date']

https://felipefrizzo.github.io/post/form-inline/ 1/5
11/03/2023, 07:46 Formulários dinâmicos com inlineformset_factory em uma aplicação Django // Felipe Frizzo

class ItemOrderForms(forms.ModelForm):
class Meta:
model = ItemOrder
exclude = ['order']

Agora iremos criar a nossa view para podermos exibir e renderizar o formulário para que
conseguimos criar um pedido com um ou vários items.

# views.py
from django.forms.models import inlineformset_factory
from django.http.response import HttpResponseRedirect
from django.shortcuts import render

from cadastro.forms import OrderForms, ItemOrderForms


from cadastro.models import Order, ItemOrder

def order(request):
order_forms = Order()
item_order_formset = inlineformset_factory(Order, ItemOrder, form=ItemOrderFo

if request.method == 'POST':
forms = OrderForms(request.POST, request.FILES, instance=order_forms, pre
formset = item_order_formset(request.POST, request.FILES, instance=order_

if forms.is_valid() and formset.is_valid():


forms = forms.save(commit=False)
forms.save()
formset.save()
return HttpResponseRedirect('/pedido/')

else:
forms = OrderForms(instance=order_forms, prefix='main')
formset = item_order_formset(instance=order_forms, prefix='product')

context = {
'forms': forms,
'formset': formset,
}

return render(request, 'order.html', context)

https://felipefrizzo.github.io/post/form-inline/ 2/5
11/03/2023, 07:46 Formulários dinâmicos com inlineformset_factory em uma aplicação Django // Felipe Frizzo

Instanciamos a classe Order .


Instanciamos o inlineformset_factory .
Order : Indicamos qual é a classe PAI.
ItemOrder : Indicamos qual é a classe FILHA.
form=ItemOrderForm : Indicamos o formulário a ser usado.
extra=1 : Indicamos quantos items teremos inicialmente quando for renderizado o
HTML .
can_delete=False : Ignoramos a opção de deletar o formulário.
min_num=1 : Indicamos a quantidade mínima de items.
validate_min=True : Habilitamos a validação do formulário

Template

{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block head_title %}{{ template_title }}{% endblock %}

{% block content %}
<script>
$(document).ready(function(){
$("#add-item").click(function(ev) {
ev.preventDefault();
var count = $('#order').children().length;
var tmplMarkup = $("#item-order").html();
var compiledTmpl = tmplMarkup.replace(/__prefix__/g, count);
$("div#order").append(compiledTmpl);

// update form count


$('#id_product-TOTAL_FORMS').attr('value', count + 1);

// some animate to scroll to view our new form


$('html, body').animate({
scrollTop: $("#add-item").position().top-200
}, 800);
});
});
</script>

<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1 class="page-header text-center lead">Cadastro Pedido</h1>
</div>
</div>
<div class="row">
<div class="col-md-8 col-md-offset-2">
https://felipefrizzo.github.io/post/form-inline/ 3/5
11/03/2023, 07:46 Formulários dinâmicos com inlineformset_factory em uma aplicação Django // Felipe Frizzo

<form action="" method="POST">


{% csrf_token %}
{{ forms|crispy }}
{{ formset.management_form }}

<legend class="lead">PRODUTOS</legend>

<div id="order" class="form-inline form-group">


{% for item_order_form in formset %}
<div id="item-{{ forloop.counter0 }}">
{{ item_order_form|crispy }}
</div>
{% endfor %}
</div>

<a class="btn btn-info" id="add-item"><i class="fa fa-plus"></i>

<div class="form-inline buttons">


<a href="{% url 'order' %}" class="btn btn-warning pull-right
<button class="btn btn-primary pull-right" value="Save"><i cl
</div>
</form>
</div>

<script type="text/html" id="item-order">


<div id="item-__prefix__" style="margin-top: 10px">
{{ formset.empty_form|crispy }}
</div>
</script>
{% endblock %}

No nosso template precisamos de uma função em JavaScript para adicionar novos formulários
de items a cada vez que for clicado no botão Add Item . Essa função irá primeiro descobrir quantos
formulários foram renderizados e em seguida vai adicionar um novo item ao formulário do Pedido .
E por ultimo irá atualizar o total de formulários de items que foram incluídos.

Documentação:
https://docs.djangoproject.com/en/1.9/ref/forms/models/#inlineformset-factory

#django #python #inline #forms #dynamic

<  Formulários dinâmicos com inlineformset_factory em uma aplicação Django utilizando Class-Based View

https://felipefrizzo.github.io/post/form-inline/ 4/5
11/03/2023, 07:46 Formulários dinâmicos com inlineformset_factory em uma aplicação Django // Felipe Frizzo

3 Comments 
1 Login

G Join the discussion…

LOG IN WITH OR SIGN UP WITH DISQUS ?

Name

 1 Share Best Newest Oldest

Marcelo Romeu Gonçalves − ⚑


2 years ago

Excelente post. Parabéns.

1 0 Reply • Share ›

Felipe Frizzo Mod > Marcelo Romeu Gonçalves


− ⚑
2 years ago

Obrigado Marcelo :D

0 0 Reply • Share ›

giooo-. − ⚑
a year ago

Estava enfrentando dificuldades com isso, você não faz ideia do quanto me ajudou.
Esclarecedor, obrigado pelo post!

0 0 Reply • Share ›

Subscribe Privacy Do Not Sell My Data

© 2020 Felipe Frizzo


Powered by Hugo with theme Minos

      

https://felipefrizzo.github.io/post/form-inline/ 5/5

Você também pode gostar