I have a form with a custom layout from "crispy forms" and an inline form manually in HTML. If I don't use custom layouts, I can save both with no problem, however I'll need to make a button to submit the forms together using layouts.
This is my HTML:
<form id="registro-form" class="main-form" action="?" method="POST">
<!-- Main Form -->
{% csrf_token %}
{% crispy form %}
<hr>
<!-- Inline Formset -->
{{ itens_formset.management_form }}
{% for formset_form in itens_formset %}
<div class="inline-formset-item">
<!-- Render inline formset fields manually -->
<div class="row no-gutters">
<!-- Render formset fields here -->
</div>
</div>
{% endfor %}
<!-- Submit Button -->
<button class="btn btn-success mt-2 mb-5" type="submit" style="width: 110px;">Salvar</button>
</form>
This is my html code at the moment, but when I click the submit button, nothing happens.
This is my views.py:
class RegistrarCreate(GroupRequiredMixin, CreateView):
# GroupRequiredMixin and other attributes
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
ItemFormSet = inlineformset_factory(Registro, Item, form=ItemForm, extra=1, can_delete=False)
if self.request.POST:
context['itens_formset'] = ItemFormSet(self.request.POST, instance=self.object)
else:
context['itens_formset'] = ItemFormSet(instance=self.object)
return context
def form_valid(self, form):
context = self.get_context_data()
itens_formset = context['itens_formset']
if itens_formset.is_valid():
self.object = form.save()
itens_formset.instance = self.object
itens_formset.save()
return super().form_valid(form)
else:
print("Formset is invalid")
print(itens_formset.errors)
return self.render_to_response(self.get_context_data(form=form))
def get(self, request, *args, **kwargs):
self.object = None
return super().get(request, *args, **kwargs)
This is my forms.py:
class RegistroForm(forms.ModelForm):
class Meta:
model = Registro
fields = ['tipo', 'vendedor', 'nome', 'cpf', 'email', 'rg', 'cidade', 'telefone', 'numero', 'rua', 'bairro', 'data']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# Personalize o layout dos campos usando Crispy Forms
self.helper = FormHelper()
self.helper.form_class = 'form'
self.helper.layout = Layout(
Div(
Div(Field('tipo', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(HTML("<h4>N° {{ registro_format }}</h4>"), css_class='col-md-5 mt-4'),
css_class='row'
),
Div(
Div(Field('nome', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(Field('cpf', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
Div(
Div(Field('email', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(Field('rg', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
Div(
Div(Field('vendedor', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(Field('data', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
Div(
Div(Field('cidade', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(Field('telefone', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
Div(
Div(Field('numero', css_class='form-control'), css_class='col-md-5'),
Div(css_class='col-md-2'),
Div(Field('rua', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
Div(
Div(Field('bairro', css_class='form-control'), css_class='col-md-5'),
css_class='row'
),
)
class ItemForm(forms.ModelForm):
class Meta:
model = Item
fields = ['quantidade', 'tamanho','valorProd', 'valor_total']
What I've Tried: I've tried to write the submit button inside the layout, but the information of the itens wasn't been passed and the program returned an empty list
Try adding an invalid function to print the form errors.
That should show any errors in the form.