6

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)
MrMotivator
  • 101
  • 1
  • 2

2 Answers2

5

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

igneosaur
  • 3,268
  • 3
  • 29
  • 44
Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • 1
    Unfortunately, this seems to only handle editing existing objects, rather than creating new ones from scratch. Thanks for the suggestion though! I might use this for my edit page. – MrMotivator Apr 18 '11 at 12:34
  • 2
    @MrMotivator Not at all - it certainly handles adding new objects. This is how the admin add/edit functionality is implemented. – Daniel Roseman Apr 18 '11 at 12:39
  • Inline formsets are really made for that – Pierre de LESPINAY Nov 09 '11 at 08:05
  • @PierredeLESPINAY it is my understanding that the default options for creating an inline formset only render the fields for the child object in 1.7, or what am I missing here? – Wtower Feb 21 '15 at 07:33
  • Link is depraciated – jedruniu May 27 '17 at 13:23
  • Wow, zero help. Here's a [better answer](https://stackoverflow.com/questions/1113047/creating-a-model-and-related-models-with-inline-formsets). – igneosaur Aug 10 '17 at 10:02
2

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

James Khoury
  • 21,330
  • 4
  • 34
  • 65
  • Yep, that would work - you rightly point out the limitation that for it to be perfect I'd need to know the number of child objects in advance (which I don't). My plan is to create a single child object at parent creation time (using your method), then allow for new ones to be added one at a time. – MrMotivator Apr 18 '11 at 12:36
  • i think you're talking about formsets? Read what Daniel Posted. – James Khoury Apr 18 '11 at 23:30