CBV with inline formset

109 views
Skip to first unread message

Brad Rice

unread,
Dec 15, 2014, 3:39:49 PM12/15/14
to django...@googlegroups.com
I've pretty much butchered the code for 3 days now and cannot figure out how to insert an inline formset. Can anybody help me?

I've tried to pare everything down to use two simple Models just to try to get an insert. I'm using django Author - Book relationship to keep it simple.

class Author(models.Model):
    name = models.CharField(max_length=100)

    def __unicode__(self):              # __unicode__ on Python 2
        return self.name


class Book(models.Model):
    name = models.CharField(max_length=100)
    author = models.ForeignKey(Author)

So I have a page where you can insert and author. The author page takes you to a page to insert books for that author using an inline formset of 3 books.

In my urls.py I have this url url(r'^book_create/(?P<author_id>\d+)/$', BookCreate.as_view(), name='book_create'),

When you go to book_create I can see the author_id getting passed in the kwargs. Now how to I insert from there books into the db with the Foreign Key to that author passed in the kwargs?

After banging away for so long, I decided to try to switch to django extra views. this is what I have in my views.py

class BookCreate(InlineFormSetView):
    model = Author
    inline_model = Book
    form_class = BookForm
    extra = 3
    template_name = 'book_template.html'

    def get_queryset(self):
        slug = self.kwargs['author_id']
        return super(BookCreate, self).get_queryset().filter(id=slug)

When I go to the book_create page I get this error:

Generic detail view BookCreate must be called with either an object pk or a slug.

Vijay Khemlani

unread,
Dec 15, 2014, 4:09:29 PM12/15/14
to django...@googlegroups.com
Try changing the name of the parameter in the url from author_id to pk

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-users...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at http://groups.google.com/group/django-users.
To view this discussion on the web visit https://groups.google.com/d/msgid/django-users/df120546-0931-4b17-93e1-70ba884e62f5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Dan Gentry

unread,
Dec 15, 2014, 4:38:13 PM12/15/14
to django...@googlegroups.com
I created a couple of mixins for a project that might help you.  See this gist: https://gist.github.com/dashdrum/03858d79ddfd9bba44d6

Pretty easy to use.  Here's an example Create view:

class RegistrationView(FormsetCreateMixin,CreateView):
   template_name = 'registration/registration_form.html'
   model = RegistrationMaster
   form_class = RegistrationForm
   detail_form_class = RegDetailFormSet

The mixin creates a new class variable: detail_form_class.  Set this in the view class declaration to point to your formset.  

I haven't tested this beyond the one project, so please tread carefully.  I hope this can at least get you moving in the right direction.



Brad Rice

unread,
Dec 15, 2014, 4:46:48 PM12/15/14
to django...@googlegroups.com
Thanks. I think I figured out how to do this with a straight createView.

class BookCreate(CreateView):
model = Book
form_class = BookForm
template_name = 'book_template.html'
success_url = u'/dp/thanks'

def get(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
author = Author.objects.get(id=self.kwargs['author_id'])
formset = BookFormset(instance=author)
return self.render_to_response(self.get_context_data(formset=formset))

def post(self, request, *args, **kwargs):
self.object = None
form_class = self.get_form_class()
author = Author.objects.get(id=self.kwargs['author_id'])
formset = BookFormset(request.POST,request.FILES,instance=author)
if formset.is_valid():
formset.save()
return HttpResponseRedirect(reverse('dp:thanks'))

def form_valid(self, formset):
   context = self.get_context_data()
   book_formset = context['formset']
   if book_formset.is_valid():
       # self.object = book_formset.save()
       book_formset.instance = self.object
       book_formset.save()
       return HttpResponseRedirect(self.get_success_url())
   else:
       return self.render_to_response(self.get_context_data(formset=book_formset))
Reply all
Reply to author
Forward
0 new messages