Using FormMixin with DetailView

489 views
Skip to first unread message

Ioannis Latousakis

unread,
Jul 27, 2015, 6:47:48 PM7/27/15
to Django users
I am on the exact same situation as the one described in the documentation here: https://docs.djangoproject.com/en/1.7/topics/class-based-views/mixins/#using-formmixin-with-detailview 

I have followed the documentation but I get the following exception:

__init__() takes exactly 1 argument (3 given)
Request Method:GET
Request URL:http://localhost:8000/post/5144752345317376/
Django Version:1.6.11
Exception Type:TypeError
Exception Value:
__init__() takes exactly 1 argument (3 given)
Exception Location:...app/sitepackages/django/core/handlers/base.py in get_response, line 11



I think the only location where I might need something different is my urls.py... Here is the complete code:


class PostView(BlogMixin,DetailView):
   
""" A view for displaying a single post """
    template_name
= 'post.html'
    model
= Post
   
def get_context_data(self, **kwargs):
        context
= super(PostView, self).get_context_data(**kwargs)
        context
['form'] = CommentForm()
       
return context
   
class PostDetailView(View):
   
print "HERE   ------------ "


   
def get(self, request, *args, **kwargs):
       
print "GET   ------------ "
        view
= PostView.as_view()
       
return view(request, *args, **kwargs)


   
def post(self, request, *args, **kwargs):
       
print "POST   ------------ "
        view
= PostComment.as_view()
       
return view(request, *args, **kwargs)


class PostComment(  SingleObjectMixin , FormView):
    template_name
= 'post.html'
    form_class
= CommentForm
    model
= Post


   
def post(self, request, *args, **kwargs):
       
self.object = self.get_object()
       
return super(PostComment, self).post(request, *args, **kwargs)


   
def get_success_url(self):
       
return reverse('post-detail', kwargs={'pk': self.object.pk})

class BlogMixin(object):
    """
    Basic mixin for all the views. Update the context with additional
    information that is required across the whole site, typically
    to render base.html properly
    """
    def get_context_data(self, *args, **kwargs):
        context = super(BlogMixin, self).get_context_data(*args, **kwargs)
        blog = Blog.get_unique()
        context.update({
            'blog': blog,
            'active_user': users.get_current_user(),
            'is_admin': users.is_current_user_admin()
        })
        return context

urls.py:
    url(r'^post/(?P<pk>[\d]+)/$', views.PostDetailView., name="post-detail"),



Before the exception, 'HERE ------" is printed, but no GET or POST

Gergely Polonkai

unread,
Jul 28, 2015, 2:53:36 AM7/28/15
to django...@googlegroups.com

Hello,

could you show us the relevant part of your urls.py file? I suspect view parameters to cause the trouble but I'd like to be sure.

Best,
Gergely

--
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/299d4e5e-0b69-4627-a1e6-e7f2d1ff9d8d%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Gergely Polonkai

unread,
Jul 28, 2015, 2:54:31 AM7/28/15
to django...@googlegroups.com

Forgot to add, the full backtrace would be helpful, too. It should be present on the same error page.

Ioannis Latousakis

unread,
Jul 28, 2015, 4:12:39 AM7/28/15
to Django users, latu...@gmail.com
Thanks your your response. I have now gone past that problem and the form renders, although on submission of the form nothing happens. The 'POST -----' string is printed, which means I am on the right track, but no new object is created. I tried to simplify the comment form (remove the FK and the method override) in case there was a problem with that code, but I still dont get a comment created. Here is the current state of the code:

class CommentForm(forms.ModelForm):
   
class Meta:
        model
= Comment
        exclude
= ("parent_post","created_at")


   
def save():
       
print "IN VIEW"
       
if request.method == "POST":
            parent_fk
= self.object
           
print "PARRENT"
           
print parent_fk
            form
= CommentForm(request.POST)
           
if form.is_valid():
                new_comment
= form.save(commit=False)
                new_comment
.parent_post = parent_fk
                new_comment
.save()
               
return HttpResponseRedirect(request.META.get('HTTP_REFERER'))


class PostView(DetailView):

   
""" A view for displaying a single post """
    template_name
= 'post.html'
    model
= Post
   
def get_context_data(self, **kwargs):
        context
= super(PostView, self).get_context_data(**kwargs)
        context
['form'] = CommentForm()
       
return context
   
class PostDetailView(View):



   
def get(self, request, *args, **kwargs):

        view
= PostView.as_view()
       
return view(request, *args, **kwargs)


   
def post(self, request, *args, **kwargs):

        view
= PostComment.as_view()
       
return view(request, *args, **kwargs)


class PostComment(  SingleObjectMixin , FormView):
    template_name
= 'post.html'
    form_class
= CommentForm
    model
= Post


   
def post(self, request, *args, **kwargs):

       
print "POST ----"

       
self.object = self.get_object()
       
return super(PostComment, self).post(request, *args, **kwargs)


   
def get_success_url(self):
       
return reverse('post-detail', kwargs={'pk': self.object.pk})





    url
(r'^post/(?P<pk>[\d]+)/$', views.PostDetailView.as_view(), name="post-detail"),



Ioannis Latousakis

unread,
Jul 28, 2015, 4:14:42 AM7/28/15
to Django users, latu...@gmail.com
The override is this, I was experimenting with save..


class CommentForm(forms.ModelForm):
   
class Meta:
        model
= Comment
        exclude
= ("parent_post","created_at")


    def create_view(request, **kwargs):

James Schneider

unread,
Jul 28, 2015, 4:32:13 AM7/28/15
to django...@googlegroups.com, latu...@gmail.com

Is there a specific reason you aren't just using CreateView rather than trying to mix in a bunch of classes and trying to roll the post() logic yourself? You can probably cut a very large portion of code out and make this super simple.

https://docs.djangoproject.com/en/1.6/topics/class-based-views/generic-editing/#model-forms

You should also consider upgrading Django immediately to a newer version, as 1.6 is no longer supported.

-James

--
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.

Ioannis Latousakis

unread,
Jul 28, 2015, 4:39:06 AM7/28/15
to Django users, jrschn...@gmail.com
Hello James,

The reason I am following this approach is because this is what was suggested in the documentation, for the scenario where you need to have a form within a DetailsView. Although even when I got my code to be identical to the documentation example, I still dont get an object created. Still, on form submit, the method get_success_url() of PostComment formview is called.  I am currently using django 1.7. 

James Schneider

unread,
Jul 28, 2015, 4:54:55 AM7/28/15
to Ioannis Latousakis, Django users

Are you sure you're using 1.7? Your original error posting begs to differ:

Django Version:1.6.11

The particular portion of docs that you are reading is meant to show how various mixin's can be used together to address specific edge cases, but other generic classes exist that are much better suited for what you are trying to do. Follow the link I posted to see examples.

The only 'tricky' portion of what you are trying to do is to attach the Comment to the Post, which is easily handled by overriding the form_valid() method in a CreateView.

You may not even need to define a Model Form.

- James

Ioannis Latousakis

unread,
Jul 28, 2015, 5:09:55 AM7/28/15
to Django users, jrschn...@gmail.com
Right.. I miss read the requirements.txt. Im new to django so started from a simple app base and building on top. On first look nothing broke when upgrading to 1.7. Ill check the docs you posted now.

James Schneider

unread,
Jul 28, 2015, 5:51:54 AM7/28/15
to Ioannis Latousakis, Django users

I've reviewed your code a bit more and I see what you're trying to do, I think.

With that being said, I'll recant what I said about the CreateView.

Your trouble stems from the fact that FormView by default does not perform a form.save() operation anywhere (it only validates the form). CreateView does this in the form_valid() method.

I'm not sure what you are doing with the create_view() method in the form, but it looks like a pseudo-save method. You probably don't need it, but that chunk off code looks like it actually belongs in form_valid() on the view, not on the form.

Look into overriding form_valid() in your view. The example you were/are looking at is missing the save() functionality, and it states so at the beginning of the section.

"Again, let’s assume we’re not going to store this in a relational database but instead in something more esoteric that we won’t worry about here."

I think that the docs are a bit misleading here, since I would expect a large section like this to at least make reference to something like "#save code here". Maybe it is in there, hard to tell on my phone.

- James

Ioannis Latousakis

unread,
Jul 28, 2015, 7:08:23 AM7/28/15
to Django users, latu...@gmail.com
Hello James,

Following your advice I turned to using CreateView, and now all the functionality I wanted seems to work fully. As you suggested there is no need for a form.py using this method. When I got more time I might investigate further how to make the original approach work for future reference.  This is the view code:

class PostDetailView(BlogMixin,CreateView):

   
""" A view for displaying a single post """
    template_name
= 'post.html'

    model
= Comment
    fields
= ['body','author_name']
   
def get_context_data(self, **kwargs):
        context
= super(PostDetailView, self).get_context_data(**kwargs)
        context
['post'] =  Post.objects.get(pk=self.kwargs['pk'])
       
return context
   
   
def form_valid(self, form):
        obj
= form.save(commit=False)
        obj
.parent_post = Post.objects.get(pk=self.kwargs['pk'])
        obj
.save()

       return redirect('post-detail', self.kwargs['pk'])


Abdu-H

unread,
Sep 7, 2020, 6:02:45 PM9/7/20
to Django users

Hello, i realise this is a very old post, but i am trying to implement your code here, but it seems some code are missing, i was able to get a form, but the contents of my detailView isn't showing, what code am i suppose to put here " A view for displaying a single post ". your help will be greatly appreciated.
Thank you.

latu...@gmail.com

unread,
Sep 13, 2020, 12:05:23 PM9/13/20
to Django users
Hello Abdu,
I haven't used FormViews in years, there have been major Django versions released since this was posted, some of the advice here may no longer be relevant. Sorry I can't help more.

Reply all
Reply to author
Forward
0 new messages