Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create parent and children model objects from one form submission

My model has a parent object, each of which can have zero or more child objects associated by foreign key.

My auto-generating ModelForm works great for the parent object, but I'd like the user to be able to create one or more of the child objects at the same time as creating the parent. Note, I don't mean pick from pre-existing child objects - I do mean create child objects from scratch...

I'm currently using lots of django magic to get the form to appear with very little boilerplate from me: I realise that will probably have to change to get this done!

Here's an idea of what I have at the moment:

# urls.py
(r'^create/$',
    CreateAppView.as_view(
        model=App,
        template_name='edit.html')),

 

# edit.html
<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ form.as_p }}
<input type="submit" value="Submit" />
</form>

 

# model
class App(models.Model):
    name = models.CharField(max_length=100)

class Activation(models.Model):
    app = models.ForeignKey(App)

 

# view
class AppForm(ModelForm):
    class Meta:
        model = App

class CreateAppView(CreateView):
    def post(self, request, *args, **kw):
        form = AppForm(request.POST)
        if form.is_valid():
            app = form.save()
            return HttpResponseRedirect(reverse('app_detail', args=(app.id,)))
        else:
            return super(CreateAppView, self).post(request, *args, **kw)
like image 934
MrMotivator Avatar asked Apr 18 '11 01:04

MrMotivator


2 Answers

Actually, all this sort of functionality is provided already in the form of inline model formsets.

like image 74
Daniel Roseman Avatar answered Oct 12 '22 13:10

Daniel Roseman


add multiple forms with different names ?

The problem then is you'll have to know how many forms are being rendered and have a much more specific template.

something like:

# edit.html
<form action="" method="post" enctype="multipart/form-data">
    {% csrf_token %}
    {{ appform.as_p }}
    {{ appform2.as_p }}
<input type="submit" value="Submit" />
</form>

and in the view:

appform= AppForm(request.POST, prefix="1")
appform2= AppForm(request.POST, prefix="2")

It will also work for diffferent models:

appform= AppForm(request.POST, prefix="app")
spamform = SpamForm(request.POST, prefix="spam")

I'm not sure about your urls.py because i've never used that function/shortcut ... thingy ;)

like image 38
James Khoury Avatar answered Oct 12 '22 14:10

James Khoury