Sorry for a newbie question but...
Can someone shed some light on what is the use case for inlineformset_factory?
I have followed example from Django documentation:
#Models
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
author = models.ForeignKey(Author)
title = models.CharField(max_length=100)
#View
def jojo(request):
BookFormSet = inlineformset_factory(Author, Book)
author = Author.objects.get(name=u'Mike Royko')
formset = BookFormSet(instance=author)
return render_to_response('jojo.html', {
'formset': formset,
})
#jojo.html
<form action="" method="POST">
<table>
{{ formset }}
</table>
<input type="submit" value="Submit" />
</form>
But it only displays book fields.
My understanding was that formset would display Book form with inline Author form just like Django Admin. On top of that I can't easily pass initial values to formset?
Then how is it better then using two separate AuthorForm and BookForm?
Or am i missing something obvious?
inlineformset_factory only provides multiple forms for the nested elements, you need a separate form at the top if you want a form for the main model.
Here is an example of a working inlineformset_factory with the main form embedded at the top:
views.py
from django.shortcuts import get_object_or_404, render_to_response
from django.forms.models import inlineformset_factory
from django.http import HttpResponseRedirect
from django.template import RequestContext
from App_name.models import * #E.g. Main, Nested, MainForm, etc.
. . .
@login_required
def Some_view(request, main_id=None, redirect_notice=None):
#login stuff . . .
c = {}
c.update(csrf(request))
c.update({'redirect_notice':redirect_notice})#Redirect notice is an optional argument I use to send user certain notifications, unrelated to this inlineformset_factory example, but useful.
#Intialization --- The start of the view specific functions
NestedFormset = inlineformset_factory(Main, Nested, can_delete=False, )
main = None
if main_id :
main = Main.objects.get(id=main_id)#get_object_or_404 is also an option
# Save new/edited Forms
if request.method == 'POST':
main_form = MainForm(request.POST, instance=main, prefix='mains')
formset = NestedFormset(request.POST, request.FILES, instance=main, prefix='nesteds')
if main_form.is_valid() and formset.is_valid():
r = main_form.save(commit=False)
#do stuff, e.g. setting any values excluded in the MainForm
formset.save()
r.save()
return HttpResponseRedirect('/Home_url/')
else:
main_form = MainForm(instance=main, prefix='mains') #initial can be used in the MainForm here like normal.
formset = NestedFormset(instance=main, prefix='nesteds')
c.update({'main_form':main_form, 'formset':formset, 'realm':realm, 'main_id':main_id})
return render_to_response('App_name/Main_nesteds.html', c, context_instance=RequestContext(request))
template.html
{% if main_form %}
<form action="." method="POST">{% csrf_token %}
{{ formset.management_form }}
<table>
{{main_form.as_table}}
{% for form in formset.forms %}
<table>{{ form }}</table>
{% endfor %}
</table>
<p><input type="submit" name="submit" value="Submit" class="button"></p>
</form>
{% endif %}