Reputation: 4460
I want to submit two forms in my template. The reason for that is, that I have two separate models, each with a model form, which I have to submit at the same time to create the desired result:
I have these two forms:
class BootstrapModelForm(ModelForm):
def __init__(self, *args, **kwargs):
super(BootstrapModelForm, self).__init__(*args, **kwargs)
for field in iter(self.fields):
self.fields[field].widget.attrs.update({
'class': 'form-control'
})
class DeckForm(ModelForm):
class Meta:
model = Deck
exclude = ('dust',)
class GuideForm(BootstrapModelForm):
class Meta:
model = Guide
exclude = ('author', 'upvotes', 'downvotes', 'release_date', 'modified', 'deck')
def __init__(self, *args, **kwargs):
super(GuideForm, self).__init__(*args, **kwargs)
self.fields['title'].label = 'Title of your AWESOME Guide!'
self.fields['public'].label = 'Check, when you want to make your guide public'
self.fields['public'].widget.attrs.update({
'class': 'checkbox'
})
self.fields['introduction'].label = 'Introduction (not required, but recommended)'
A deck is a part of the Guide that gets created. Since the user should be able to create his own deck while writing his guide, I need two forms.
In my views I handled it like this:
def guide_create(request):
if request.method == "POST":
deck_form = DeckForm(request.POST)
guide_form = GuideForm(request.POST)
if guide_form.is_valid() and deck_form.is_valid():
new_deck = deck_form.save(commit=False)
new_deck.dust = 0
new_deck.save()
new_guide = deck_form.save(commit=False)
new_guide.author = Account.objects.get(id=request.user.id)
new_guide.deck = Deck.objects.get(id=new_deck.id)
new_guide.save()
else:
print(guide_form.errors)
print(deck_form.errors)
else:
deck_form = DeckForm(prefix = 'DeckForm')
guide_form = GuideForm(prefix = 'GuideForm')
return render(request, 'hsguides/guide_create.html', {
'DeckForm': DeckForm,
'GuideForm': GuideForm,
})
I use commit=False
so I still can insert the deck in my guide. Now my problem comes with creating the template. When I submit the forms with my current set up, I receive no errors any more but the guide and the deck aren't saved either!
<div style="width: 60%; margin: 0 auto;">
<form class="form-horizontal" method="POST" action="{% url 'GuideCreate' %}"> {% csrf_token %}
<fieldset>
{% for field in DeckForm %}
{% if field.errors %}
<div class="class-group error">
<label class="control-lable">{{ field.label }}</label>
<div class="controls">{{ field }}
<span class="help-inline">
{% for error in field.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="control-group">
<label class="control-label">{{ field.label }}</label>
<div class="controls">{{ field }}</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
<fieldset>
{% for field in GuideForm %}
{% if field.errors %}
<div class="class-group error">
<label class="control-lable">{{ field.label }}</label>
<div class="controls">{{ field }}
<span class="help-inline">
{% for error in field.errors %}{{ error }}{% endfor %}
</span>
</div>
</div>
{% else %}
<div class="control-group">
<label class="control-label">{{ field.label }}</label>
<div class="controls">{{ field }}</div>
</div>
{% endif %}
{% endfor %}
</fieldset>
<div class="form-actions" style="margin-top: 4px;">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</form>
</div>
Edit I don't receive an error message any more, the deck gets created as well but the guide that belongs to it not.
Upvotes: 1
Views: 388
Reputation: 7622
You're saying the guide doesn't get created. I see this line new_guide = deck_form.save(commit=False)
..... shouldn't it be new_guide = guide_form.save(commit=False)
?
Not 100% but this might be a mistake. Hopefully, it's not just because you refactored the code for putting it here.
Upvotes: 1
Reputation: 1520
Just Change
return render_to_response('hsguides/guide_create.html', {
'DeckForm': DeckForm,
'GuideForm': GuideForm,
})
to
return render(request,'hsguides/guide_create.html', {
'DeckForm': DeckForm,
'GuideForm': GuideForm,
})
Upvotes: 2
Reputation: 25559
Try this, you might forgot to pass the RequestContext
:
from django.template import RequestContext
return render_to_response('hsguides/guide_create.html',
{'DeckForm': DeckForm, 'GuideForm': GuideForm},
RequestContext(request))
It passes the csrf token to the template.
Upvotes: 1
Reputation: 37934
I didnot check the whole thing, but this place is wrong, it should be:
if request.method == "POST":
deck = DeckForm(request.POST)
if deck.is_valid():
# ....
you are not packing the POST data into your forms..
the same goes for the second form as well
Upvotes: 1