MrMotivator
MrMotivator

Reputation: 101

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)

Upvotes: 6

Views: 6875

Answers (2)

Daniel Roseman
Daniel Roseman

Reputation: 599610

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

Upvotes: 5

James Khoury
James Khoury

Reputation: 22319

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 ;)

Upvotes: 2

Related Questions