Controllers

Return to Core.

This module extends standard Django function views and allows us to use so called class-based-views. Django itself contains many features to power up class based approach to the topic (for instance django.utils.decorators.method_decorator).

During development of django-projector we just copied codes much too often and class-based views allow us to complete many tasks in a much simpler way.

View

class projector.core.controllers.View(request, *args, **kwargs)

Main view class. Implemntation is focused around __call__ method and classmethod new.

Subclasses should implement response method but it is not required.

Class-level attributes:

Attribute login_required:
 Default: False. If set to True, response method would be wrapped with standard django.contrib.auth.decorators.login_required.
Attribute template_name:
 Default: 'base.html' If response method returns a dict then this value is used to render context.

Instance-available attributes:

Attribute self.context:
 Context dictionary. During initialization it is set to empty dict ({}).
Attribute self.request:
 django.http.HttpRequest instance passed in by the url resolver.
Attribute self.args:
 Positional parameters passed in by url resolver.
Attribute self.kwargs:
 Named parameters passed in by url resolver.

Implementation example:

from projector.core.controllers import View
from projector.models import Project

class ProjectList(View):

    login_required = True
    template_name = 'project_list.html'

    def response(self, request):
        self.context = Project.objects.all()
        return self.context

class ProjectDetail(View):

    login_required = True
    template_name = 'project_detail.html'

    def response(self, request, project_id):
        self.context['project'] = get_object_or_404(Project, id=project_id)
        return self.context

Typically, we would hook such defined views at urls.py module:

from django.conf.urls.defaults import *

urlpatterns = patterns('projector.views',
    (r'^projects/$', 'ProjectList'),
    (r'^projects/(?P<project_id>\d+)/$', 'ProjectDetail'),
)

Note that url resolvers pass all parameters to the given functions. Our subclasses of View class are treated very similar to functions as they should return HttpResponse object after being called.

response(request, *args, **kwargs)

Should be overridden at subclass. It always requires django.http.HttpRequest instance to be passed as first positional argument.

May return a dict or django.http.HttpResponse instance. If dict is returned it is treated as context and view would try to render it using self.template_name.

Returns:dict or django.http.HttpResponse instance
__before__()

Method called just after class is created and all passed parameters are set on the class, so it is possible to access those attributes.

If this method would return django.http.HttpResponse instance, it would be propagated.

__after__()

Method called at the final step of the view-class processing. If django.http.HttpResponse instance is returned it is propagated to the view handler.

Note

Adding i.e. context at this stage is pointless - response should have been already prepared and changing context wouldn’t change the response. __after__ method should be implemented for other purposes, like checking status code of prepared response. Response object is available by accessing self._response. This attribute is available only at this stage.

__call__()

Should be overridden only for special cases as it runs __after__ method after response method is executed. By subclassing it is possible to change the order of method calls.

Table Of Contents

Previous topic

Core

Next topic

Exceptions

This Page