Class Based Views: CreateView Example

For this example I’m not starting with a generic view. That’s because the code includes support for an extra submit button – in this case “Save and Add Another”. Without it, I would have used the generic view.

Before:

@permission_required('calendars.add_eventtype')
def create_type(request):
    evttypeform = EventTypeForm(request.POST or None)
    
    if evttypeform.is_valid():
        evttypeform.save()
        if '_addanother' in request.POST:
            return HttpResponseRedirect(reverse('create_type'))
    
        return HttpResponseRedirect(reverse('list_type'))
            
    return render_to_response('eventtype_form.html', 
                              {'form' : evttypeform, 'create_form': True,
                    'calendar_menu': CalendarName.menu.all(),   },
                               context_instance=RequestContext(request))

Perhaps the Generic View would have looked something like this (not tested):

@permission_required('calendars.add_eventtype')
def create_type(request):
    return create_object(request,
                         form_class = EventTypeForm,
                         post_save_redirect=reverse('list_type'),
                         template_name='eventtype_form.html',
                         extra_context={'create_form': True,
                                        'calendar_menu': CalendarName.menu.all(),})    

After:

class TypeCreateView(CreateView):
    template_name = 'eventtype_form.html'
    model = EventType
    form_class = EventTypeForm
    
    def get_success_url(self):
        if '_addanother' in self.request.POST:
            return reverse('create_type')
        return reverse('list_type')
    
    ## Override dispatch to apply the permission decorator
    @method_decorator(permission_required('calendars.add_eventtype'))
    def dispatch(self, request, *args, **kwargs):
        return super(TypeCreateView, self).dispatch(request, *args, **kwargs)
    
    ## Additional context
    def get_context_data(self, **kwargs):
        context = super(TypeCreateView, self).get_context_data(**kwargs)
        context['calendar_menu'] = CalendarName.menu.all()
        context['create_form'] = True
        return context 

One of the benefits of the class based views is to be able to override individual methods. Here the get_success_url method can handle the extra functionality of the “Add Another” button.

Comments are closed.