Django formset : Save multiple forms from formset
I spent several days in order to add dynamically forms to formset
and I find a way to do that. But I have a little issue with forms saving
because it just saves the first form and not all forms from formset.
This is my formset :
DocumentFormSets = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4)
This is my template :
<fieldset>
<legend class="title"><span class="name">% trans 'Document form' %</span></legend>
DocumentFormSet.management_form
<div id="form_set">
% for form in DocumentFormSet.forms %
<div class='formset-document'>
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
form.format
</div>
<div class="col-xs-3">
form.upload
</div>
</div>
</table>
</div>
% endfor %
</div>
<br>
<input type="button" class="btn btn-default" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
DocumentFormSet.empty_form.title
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.language
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.upload
</div>
</div>
</table>
</div>
</fieldset>
This is my JS part :
$('#add_more').click(function ()
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
And this is my views.py file :
class PublicationCreateView(EdqmCreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'freepub/publication/publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
context['DocumentFormSets'] = DocumentFormSets(self.request.POST or None, self.request.FILES or None)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
But with this function, it saves only the first document form in my formset :
I looked over id document form field and I get this :
The first title field get id_documents-0-title
but when I add more forms, title field get always id_documents-undefined-title
How I can save my document forms from formsets ?
Thank you !
EDIT :
This is an edit from @HaiLang question :
This is my self.request.POST
:
<QueryDict: 'csrfmiddlewaretoken': ['0LHaaEG1dkyZmOnP3X7037tZI45QrQOIRrQQAMhiOoTyeohDwQdcdTt08yuqH86Z'], 'category': ['23'], 'pub_id': ['PUBSDDD-55'], 'title': ['TESTPUBLIE'], 'description': [''], 'doc-TOTAL_FORMS': ['1'], 'doc-INITIAL_FORMS': ['0'], 'doc-MIN_NUM_FORMS': ['0'], 'doc-MAX_NUM_FORMS': ['4'], 'doc-0-title': ['doc1'], 'doc-0-language': ['FR'], 'doc-0-format': ['pdf'], 'doc-undefined-title': ['doc2'], 'doc-undefined-language': ['FR'], 'doc-undefined-format': ['pdf'], 'doc-__prefix__-title': [''], 'doc-__prefix__-language': [''], 'doc-__prefix__-format': [''], 'doc-__prefix__-upload': ['']>
And this is my console.log
:
Element kt.fn.init
django django-forms formset
|
show 4 more comments
I spent several days in order to add dynamically forms to formset
and I find a way to do that. But I have a little issue with forms saving
because it just saves the first form and not all forms from formset.
This is my formset :
DocumentFormSets = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4)
This is my template :
<fieldset>
<legend class="title"><span class="name">% trans 'Document form' %</span></legend>
DocumentFormSet.management_form
<div id="form_set">
% for form in DocumentFormSet.forms %
<div class='formset-document'>
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
form.format
</div>
<div class="col-xs-3">
form.upload
</div>
</div>
</table>
</div>
% endfor %
</div>
<br>
<input type="button" class="btn btn-default" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
DocumentFormSet.empty_form.title
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.language
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.upload
</div>
</div>
</table>
</div>
</fieldset>
This is my JS part :
$('#add_more').click(function ()
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
And this is my views.py file :
class PublicationCreateView(EdqmCreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'freepub/publication/publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
context['DocumentFormSets'] = DocumentFormSets(self.request.POST or None, self.request.FILES or None)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
But with this function, it saves only the first document form in my formset :
I looked over id document form field and I get this :
The first title field get id_documents-0-title
but when I add more forms, title field get always id_documents-undefined-title
How I can save my document forms from formsets ?
Thank you !
EDIT :
This is an edit from @HaiLang question :
This is my self.request.POST
:
<QueryDict: 'csrfmiddlewaretoken': ['0LHaaEG1dkyZmOnP3X7037tZI45QrQOIRrQQAMhiOoTyeohDwQdcdTt08yuqH86Z'], 'category': ['23'], 'pub_id': ['PUBSDDD-55'], 'title': ['TESTPUBLIE'], 'description': [''], 'doc-TOTAL_FORMS': ['1'], 'doc-INITIAL_FORMS': ['0'], 'doc-MIN_NUM_FORMS': ['0'], 'doc-MAX_NUM_FORMS': ['4'], 'doc-0-title': ['doc1'], 'doc-0-language': ['FR'], 'doc-0-format': ['pdf'], 'doc-undefined-title': ['doc2'], 'doc-undefined-language': ['FR'], 'doc-undefined-format': ['pdf'], 'doc-__prefix__-title': [''], 'doc-__prefix__-language': [''], 'doc-__prefix__-format': [''], 'doc-__prefix__-upload': ['']>
And this is my console.log
:
Element kt.fn.init
django django-forms formset
to make things easier to read, you should use a plural for your formset. But why are you assigning something todocument
and savingdocument
inside the for loop ifdocument
is your formset?
– dirkgroten
Nov 12 '18 at 16:18
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I addedget_context_data
in my question. The issue is on line :self.object = form.save()
– Essex
Nov 12 '18 at 16:38
isDocumentFormset
created using aninlineformset_factory
?
– dirkgroten
Nov 12 '18 at 16:59
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01
|
show 4 more comments
I spent several days in order to add dynamically forms to formset
and I find a way to do that. But I have a little issue with forms saving
because it just saves the first form and not all forms from formset.
This is my formset :
DocumentFormSets = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4)
This is my template :
<fieldset>
<legend class="title"><span class="name">% trans 'Document form' %</span></legend>
DocumentFormSet.management_form
<div id="form_set">
% for form in DocumentFormSet.forms %
<div class='formset-document'>
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
form.format
</div>
<div class="col-xs-3">
form.upload
</div>
</div>
</table>
</div>
% endfor %
</div>
<br>
<input type="button" class="btn btn-default" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
DocumentFormSet.empty_form.title
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.language
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.upload
</div>
</div>
</table>
</div>
</fieldset>
This is my JS part :
$('#add_more').click(function ()
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
And this is my views.py file :
class PublicationCreateView(EdqmCreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'freepub/publication/publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
context['DocumentFormSets'] = DocumentFormSets(self.request.POST or None, self.request.FILES or None)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
But with this function, it saves only the first document form in my formset :
I looked over id document form field and I get this :
The first title field get id_documents-0-title
but when I add more forms, title field get always id_documents-undefined-title
How I can save my document forms from formsets ?
Thank you !
EDIT :
This is an edit from @HaiLang question :
This is my self.request.POST
:
<QueryDict: 'csrfmiddlewaretoken': ['0LHaaEG1dkyZmOnP3X7037tZI45QrQOIRrQQAMhiOoTyeohDwQdcdTt08yuqH86Z'], 'category': ['23'], 'pub_id': ['PUBSDDD-55'], 'title': ['TESTPUBLIE'], 'description': [''], 'doc-TOTAL_FORMS': ['1'], 'doc-INITIAL_FORMS': ['0'], 'doc-MIN_NUM_FORMS': ['0'], 'doc-MAX_NUM_FORMS': ['4'], 'doc-0-title': ['doc1'], 'doc-0-language': ['FR'], 'doc-0-format': ['pdf'], 'doc-undefined-title': ['doc2'], 'doc-undefined-language': ['FR'], 'doc-undefined-format': ['pdf'], 'doc-__prefix__-title': [''], 'doc-__prefix__-language': [''], 'doc-__prefix__-format': [''], 'doc-__prefix__-upload': ['']>
And this is my console.log
:
Element kt.fn.init
django django-forms formset
I spent several days in order to add dynamically forms to formset
and I find a way to do that. But I have a little issue with forms saving
because it just saves the first form and not all forms from formset.
This is my formset :
DocumentFormSets = inlineformset_factory(Publication, Document, form=DocumentForm, extra=1, max_num=4)
This is my template :
<fieldset>
<legend class="title"><span class="name">% trans 'Document form' %</span></legend>
DocumentFormSet.management_form
<div id="form_set">
% for form in DocumentFormSet.forms %
<div class='formset-document'>
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
form.format
</div>
<div class="col-xs-3">
form.upload
</div>
</div>
</table>
</div>
% endfor %
</div>
<br>
<input type="button" class="btn btn-default" value="Add More" id="add_more">
<div id="empty_form" style="display:none">
<table class='no_error'>
<div class="row">
<div class="col-xs-3">
DocumentFormSet.empty_form.title
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.language
</div>
<div class="col-xs-3">
as_crispy_field
</div>
<div class="col-xs-3">
DocumentFormSet.empty_form.upload
</div>
</div>
</table>
</div>
</fieldset>
This is my JS part :
$('#add_more').click(function ()
var form_idx = $('#id_form-TOTAL_FORMS').val();
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
);
And this is my views.py file :
class PublicationCreateView(EdqmCreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'freepub/publication/publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
context['DocumentFormSets'] = DocumentFormSets(self.request.POST or None, self.request.FILES or None)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
But with this function, it saves only the first document form in my formset :
I looked over id document form field and I get this :
The first title field get id_documents-0-title
but when I add more forms, title field get always id_documents-undefined-title
How I can save my document forms from formsets ?
Thank you !
EDIT :
This is an edit from @HaiLang question :
This is my self.request.POST
:
<QueryDict: 'csrfmiddlewaretoken': ['0LHaaEG1dkyZmOnP3X7037tZI45QrQOIRrQQAMhiOoTyeohDwQdcdTt08yuqH86Z'], 'category': ['23'], 'pub_id': ['PUBSDDD-55'], 'title': ['TESTPUBLIE'], 'description': [''], 'doc-TOTAL_FORMS': ['1'], 'doc-INITIAL_FORMS': ['0'], 'doc-MIN_NUM_FORMS': ['0'], 'doc-MAX_NUM_FORMS': ['4'], 'doc-0-title': ['doc1'], 'doc-0-language': ['FR'], 'doc-0-format': ['pdf'], 'doc-undefined-title': ['doc2'], 'doc-undefined-language': ['FR'], 'doc-undefined-format': ['pdf'], 'doc-__prefix__-title': [''], 'doc-__prefix__-language': [''], 'doc-__prefix__-format': [''], 'doc-__prefix__-upload': ['']>
And this is my console.log
:
Element kt.fn.init
django django-forms formset
django django-forms formset
edited Nov 15 '18 at 13:20
Essex
asked Nov 12 '18 at 16:08
EssexEssex
2,57911655
2,57911655
to make things easier to read, you should use a plural for your formset. But why are you assigning something todocument
and savingdocument
inside the for loop ifdocument
is your formset?
– dirkgroten
Nov 12 '18 at 16:18
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I addedget_context_data
in my question. The issue is on line :self.object = form.save()
– Essex
Nov 12 '18 at 16:38
isDocumentFormset
created using aninlineformset_factory
?
– dirkgroten
Nov 12 '18 at 16:59
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01
|
show 4 more comments
to make things easier to read, you should use a plural for your formset. But why are you assigning something todocument
and savingdocument
inside the for loop ifdocument
is your formset?
– dirkgroten
Nov 12 '18 at 16:18
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I addedget_context_data
in my question. The issue is on line :self.object = form.save()
– Essex
Nov 12 '18 at 16:38
isDocumentFormset
created using aninlineformset_factory
?
– dirkgroten
Nov 12 '18 at 16:59
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01
to make things easier to read, you should use a plural for your formset. But why are you assigning something to
document
and saving document
inside the for loop if document
is your formset?– dirkgroten
Nov 12 '18 at 16:18
to make things easier to read, you should use a plural for your formset. But why are you assigning something to
document
and saving document
inside the for loop if document
is your formset?– dirkgroten
Nov 12 '18 at 16:18
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I added
get_context_data
in my question. The issue is on line : self.object = form.save()
– Essex
Nov 12 '18 at 16:38
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I added
get_context_data
in my question. The issue is on line : self.object = form.save()
– Essex
Nov 12 '18 at 16:38
is
DocumentFormset
created using an inlineformset_factory
?– dirkgroten
Nov 12 '18 at 16:59
is
DocumentFormset
created using an inlineformset_factory
?– dirkgroten
Nov 12 '18 at 16:59
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01
|
show 4 more comments
1 Answer
1
active
oldest
votes
Luckily I just worked with FormSet recently so I can see the issue with the code in question.
(Edited by Ducky. Thank you!)
You have to set the same prefix
between your views.py file and your app.js file. Because in your view file you are using prefix='doc'
and in your javascript function you used form
prefix.
So in your JQuery file you have to write :
(function ($)
$('#add_more').click(function ()
var form_idx = $('#id_doc-TOTAL_FORMS').val();
// For debugging the issue
// console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
console.log('Element', $('#id_doc-TOTAL_FORMS'));
);
)(jQuery)
You can overwrite your view like this :
class PublicationCreateView(CreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
// For debugging
// print(self.request.POST)
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
Thank you with your answer. But I have some black points : The first one, the print in the console is :Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined asundefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.
– Essex
Nov 15 '18 at 8:36
So theNum of forms undefined
in console confirms that the error is at form_idx. Now you can update the script toconsole.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?
– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please putprint(self.request.POST)
beforeformsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.
– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has theid_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file?<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
Could you please updateid_form-TOTAL_FORMS
in javascript toid_doc-TOTAL_FORMS
? That is because in your management_form, it usedoc
instead ofform
.
– Hai Lang
Nov 15 '18 at 13:30
|
show 3 more comments
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53265969%2fdjango-formset-save-multiple-forms-from-formset%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
Luckily I just worked with FormSet recently so I can see the issue with the code in question.
(Edited by Ducky. Thank you!)
You have to set the same prefix
between your views.py file and your app.js file. Because in your view file you are using prefix='doc'
and in your javascript function you used form
prefix.
So in your JQuery file you have to write :
(function ($)
$('#add_more').click(function ()
var form_idx = $('#id_doc-TOTAL_FORMS').val();
// For debugging the issue
// console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
console.log('Element', $('#id_doc-TOTAL_FORMS'));
);
)(jQuery)
You can overwrite your view like this :
class PublicationCreateView(CreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
// For debugging
// print(self.request.POST)
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
Thank you with your answer. But I have some black points : The first one, the print in the console is :Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined asundefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.
– Essex
Nov 15 '18 at 8:36
So theNum of forms undefined
in console confirms that the error is at form_idx. Now you can update the script toconsole.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?
– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please putprint(self.request.POST)
beforeformsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.
– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has theid_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file?<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
Could you please updateid_form-TOTAL_FORMS
in javascript toid_doc-TOTAL_FORMS
? That is because in your management_form, it usedoc
instead ofform
.
– Hai Lang
Nov 15 '18 at 13:30
|
show 3 more comments
Luckily I just worked with FormSet recently so I can see the issue with the code in question.
(Edited by Ducky. Thank you!)
You have to set the same prefix
between your views.py file and your app.js file. Because in your view file you are using prefix='doc'
and in your javascript function you used form
prefix.
So in your JQuery file you have to write :
(function ($)
$('#add_more').click(function ()
var form_idx = $('#id_doc-TOTAL_FORMS').val();
// For debugging the issue
// console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
console.log('Element', $('#id_doc-TOTAL_FORMS'));
);
)(jQuery)
You can overwrite your view like this :
class PublicationCreateView(CreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
// For debugging
// print(self.request.POST)
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
Thank you with your answer. But I have some black points : The first one, the print in the console is :Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined asundefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.
– Essex
Nov 15 '18 at 8:36
So theNum of forms undefined
in console confirms that the error is at form_idx. Now you can update the script toconsole.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?
– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please putprint(self.request.POST)
beforeformsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.
– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has theid_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file?<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
Could you please updateid_form-TOTAL_FORMS
in javascript toid_doc-TOTAL_FORMS
? That is because in your management_form, it usedoc
instead ofform
.
– Hai Lang
Nov 15 '18 at 13:30
|
show 3 more comments
Luckily I just worked with FormSet recently so I can see the issue with the code in question.
(Edited by Ducky. Thank you!)
You have to set the same prefix
between your views.py file and your app.js file. Because in your view file you are using prefix='doc'
and in your javascript function you used form
prefix.
So in your JQuery file you have to write :
(function ($)
$('#add_more').click(function ()
var form_idx = $('#id_doc-TOTAL_FORMS').val();
// For debugging the issue
// console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
console.log('Element', $('#id_doc-TOTAL_FORMS'));
);
)(jQuery)
You can overwrite your view like this :
class PublicationCreateView(CreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
// For debugging
// print(self.request.POST)
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
Luckily I just worked with FormSet recently so I can see the issue with the code in question.
(Edited by Ducky. Thank you!)
You have to set the same prefix
between your views.py file and your app.js file. Because in your view file you are using prefix='doc'
and in your javascript function you used form
prefix.
So in your JQuery file you have to write :
(function ($)
$('#add_more').click(function ()
var form_idx = $('#id_doc-TOTAL_FORMS').val();
// For debugging the issue
// console.log('Element', $('#id_doc-TOTAL_FORMS'), 'Num of forms', form_idx);
$('#form_set').append($('#empty_form').html().replace(/__prefix__/g, form_idx));
$('#id_doc-TOTAL_FORMS').val(parseInt(form_idx) + 1);
console.log('Element', $('#id_doc-TOTAL_FORMS'));
);
)(jQuery)
You can overwrite your view like this :
class PublicationCreateView(CreateView):
""" Create publication with document form through formset """
model = Publication
template_name = 'publication_form.html'
def get_context_data(self, **kwargs):
context = super(PublicationCreateView, self).get_context_data(**kwargs)
document_queryset = Document.objects.all()
context['DocumentFormSets'] = DocumentFormSet(self.request.POST or None, self.request.FILES or None, prefix='doc', queryset=document_queryset)
return context
def form_valid(self, form):
context = self.get_context_data()
formsets = context['DocumentFormSets']
// For debugging
// print(self.request.POST)
if form.is_valid() and formsets.is_valid():
self.object = form.save()
formsets.instance = self.object
formsets.save()
return super(PublicationCreateView, self).form_valid(form)
edited Nov 15 '18 at 14:04
answered Nov 15 '18 at 8:15
Hai LangHai Lang
46026
46026
Thank you with your answer. But I have some black points : The first one, the print in the console is :Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined asundefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.
– Essex
Nov 15 '18 at 8:36
So theNum of forms undefined
in console confirms that the error is at form_idx. Now you can update the script toconsole.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?
– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please putprint(self.request.POST)
beforeformsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.
– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has theid_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file?<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
Could you please updateid_form-TOTAL_FORMS
in javascript toid_doc-TOTAL_FORMS
? That is because in your management_form, it usedoc
instead ofform
.
– Hai Lang
Nov 15 '18 at 13:30
|
show 3 more comments
Thank you with your answer. But I have some black points : The first one, the print in the console is :Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined asundefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.
– Essex
Nov 15 '18 at 8:36
So theNum of forms undefined
in console confirms that the error is at form_idx. Now you can update the script toconsole.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?
– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please putprint(self.request.POST)
beforeformsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement$('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.
– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has theid_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file?<input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
Could you please updateid_form-TOTAL_FORMS
in javascript toid_doc-TOTAL_FORMS
? That is because in your management_form, it usedoc
instead ofform
.
– Hai Lang
Nov 15 '18 at 13:30
Thank you with your answer. But I have some black points : The first one, the print in the console is :
Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined as undefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.– Essex
Nov 15 '18 at 8:36
Thank you with your answer. But I have some black points : The first one, the print in the console is :
Num of forms undefined
each time I add a new form in my formset. I have to see why it's defined as undefined
. Then according to your views part, if I save all at once, it saves just the first form in my formset. If I try to save one by one, it saves none documents.– Essex
Nov 15 '18 at 8:36
So the
Num of forms undefined
in console confirms that the error is at form_idx. Now you can update the script to console.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?– Hai Lang
Nov 15 '18 at 12:28
So the
Num of forms undefined
in console confirms that the error is at form_idx. Now you can update the script to console.log('Element', $('#id_form-TOTAL_FORMS'));
That is to confirm that the input in management_form can be retrieved. The $ sign is isgnature of jQuery. Have you include jQuery script in your HTML header?– Hai Lang
Nov 15 '18 at 12:28
About saving form, could you please put
print(self.request.POST)
before formsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.– Hai Lang
Nov 15 '18 at 12:30
About saving form, could you please put
print(self.request.POST)
before formsets =
and provide the output? That is to confirm posted data to have enough forms. I believe the statement $('#id_form-TOTAL_FORMS').val(parseInt(form_idx) + 1);
did not do its job to update total number of forms.– Hai Lang
Nov 15 '18 at 12:30
Below is my management_form in generated HTML file. It has the
id_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file? <input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
Below is my management_form in generated HTML file. It has the
id_form-TOTAL_FORMS
required by javascript. Could you please provide the same in your generated HTML file? <input type="hidden" name="form-TOTAL_FORMS" value="4" id="id_form-TOTAL_FORMS" /><input type="hidden" name="form-INITIAL_FORMS" value="1" id="id_form-INITIAL_FORMS" /><input type="hidden" name="form-MIN_NUM_FORMS" value="0" id="id_form-MIN_NUM_FORMS" /><input type="hidden" name="form-MAX_NUM_FORMS" value="1000" id="id_form-MAX_NUM_FORMS" />
– Hai Lang
Nov 15 '18 at 13:05
1
1
Could you please update
id_form-TOTAL_FORMS
in javascript to id_doc-TOTAL_FORMS
? That is because in your management_form, it use doc
instead of form
.– Hai Lang
Nov 15 '18 at 13:30
Could you please update
id_form-TOTAL_FORMS
in javascript to id_doc-TOTAL_FORMS
? That is because in your management_form, it use doc
instead of form
.– Hai Lang
Nov 15 '18 at 13:30
|
show 3 more comments
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53265969%2fdjango-formset-save-multiple-forms-from-formset%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
to make things easier to read, you should use a plural for your formset. But why are you assigning something to
document
and savingdocument
inside the for loop ifdocument
is your formset?– dirkgroten
Nov 12 '18 at 16:18
Also on which line exactly do you get the error? And show us how you construct the formset (your get_context_data)
– dirkgroten
Nov 12 '18 at 16:23
@dirkgroten It's the first time I use formsets, so some things are a bit unclear yet. I added
get_context_data
in my question. The issue is on line :self.object = form.save()
– Essex
Nov 12 '18 at 16:38
is
DocumentFormset
created using aninlineformset_factory
?– dirkgroten
Nov 12 '18 at 16:59
Yes exactly ! I edited my code in order to show you missing elements.
– Essex
Nov 12 '18 at 17:01