Sam
Sam

Reputation: 388

how to have multiple forms in a class based view

I have a simple blog app that you can post news and blog on it. I wanted to show the latest posts on the main page, so I created this class like this:

class MainListView(TemplateView):
    template_name = 'Blog/Home.html'

    def get_context_data(self, **kwargs):
        context = super(MainListView, self).get_context_data(**kwargs)
        context['news'] = NEWS.objects.order_by('-published')[:2]
        context['posts'] = POSTS.objects.order_by('-published')[:3]
        return context

and it works great. however, I wanted to add two additional forms to the main page too. so I added these two functions to the class:

    def get(self, request, *args, **kwargs):
        return self.render_to_response({'aform': HomeGholakForm(prefix='aform_pre'), 'bform': 
            HomeContactForm(prefix='bform_pre')})

    def post(self, request, *args, **kwargs):
        aform = _get_form(request, HomeGholakForm, 'aform_pre')
        bform = _get_form(request, HomeContactForm, 'bform_pre')
        if aform.is_bound and aform.is_valid():
            aform.save()
            return redirect('Home-Page')
        elif bform.is_bound and bform.is_valid():
            bform.save()
            return redirect('Home-Page')
        return self.render_to_response({'aform': aform, 'bform': bform})

and above this class I created a _get_form function in order for it to work:

def _get_form(request, formcls, prefix):
    data = request.POST if prefix in request.POST else None
    return formcls(data, prefix=prefix)

in the final stage I added the forms to my template like this:

         <form action="">
            {% csrf_token %}
            {{bform.email}}
            <input type="submit" name="{{bform.prefix}}" class="btn"  />
            
        </form>
        <form action="">
            {% csrf_token %}
            {{aform.info}}
            <input type="submit" name="{{aform.prefix}}" class="btn"  />
            
        </form>

After I did this, the forms both work fine, but the latest blog and news are not shown. what am I supposed to do?

Upvotes: 2

Views: 1246

Answers (1)

Abdul Aziz Barkat
Abdul Aziz Barkat

Reputation: 21807

get_context_data is normally called by the get or post method whichever is used (only get in TemplateView) and passed as the context while rendering. You override these methods but never call get_context_data. Change your get and post methods like so:

def get(self, request, *args, **kwargs):
    context = self.get_context_data(**kwargs)
    context.update({'aform': HomeGholakForm(prefix='aform_pre'), 'bform': HomeContactForm(prefix='bform_pre')})
    return self.render_to_response(context)

def post(self, request, *args, **kwargs):
    aform = _get_form(request, HomeGholakForm, 'aform_pre')
    bform = _get_form(request, HomeContactForm, 'bform_pre')
    if aform.is_bound and aform.is_valid():
        aform.save()
        return redirect('Home-Page')
    elif bform.is_bound and bform.is_valid():
        bform.save()
        return redirect('Home-Page')
    context = self.get_context_data(**kwargs)
    context.update({'aform': aform, 'bform': bform})
    return self.render_to_response(context)

You should consider making some Mixin along the lines of FormMixin which would make your work more easier.

Upvotes: 2

Related Questions