Class Based Views
Links
Note: The following links are useful, and helpful, but best to look in the actual source code:
Diagram
../misc/class-based-views.pdf
Learning
CreateView and UpdateView both have the form_valid method which can
be used to add extra data to the form instance data before it is saved. As a
general principle, I think we should only use form_valid when the data we
want to add is available in the view, but not in the form
e.g. self.request.user.
If the data is available in the form, then we should override the form save
method.
Request
The request object is available as self.request e.g.
self.request.user. Note: For this to work you will probably need the
django.core.context_processors.request context processor.
Sample
JSON
import decimal
import simplejson
from django.http import HttpResponse
from django.utils.cache import add_never_cache_headers
class DecimalEncoder(simplejson.JSONEncoder):
def default(self, obj):
if isinstance(obj, decimal.Decimal):
return str(obj)
return super(DecimalEncoder, self).default(obj)
def dumps(*args, **kwargs):
return simplejson.dumps(
*args,
sort_keys=True,
separators=(',', ': '),
indent=4,
use_decimal=False,
cls=DecimalEncoder,
**kwargs
)
def loads(*args, **kwargs):
return simplejson.loads(*args, **kwargs)
class JsonResponse(HttpResponse):
def __init__(self, request, content, **kwargs):
data = dumps(content)
try:
if "application/json" in request.META['HTTP_ACCEPT_ENCODING']:
mimetype = 'application/json'
else:
raise KeyError('application/json not accepted')
except:
mimetype = 'text/plain'
super(JsonResponse, self).__init__(data, mimetype, **kwargs)
add_never_cache_headers(self)
from django.views.generic import View
from somewhere.above import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
class MyView(View):
@method_decorator(csrf_exempt)
def dispatch(self, *args, **kwargs):
return super(MyView, self).dispatch(*args, **kwargs)
def get(self, request):
return JsonResponse(request, { 'foo': 'bar'})
def post(self, request):
data = request.POST
print data
return JsonResponse(request, {
'response': data
})
List
From passing parameters to filter of view, you can override the views
get_queryset method:
from django.views.generic.list import ListView
class MyList(ListView):
def get_queryset(self):
return Village.objects.filter(county__in='Devon')
Login
Template
from django.views.generic.base import TemplateView
class SomeView(TemplateView):
template_name = 'my_app/someview.html'
def get_context_data(self, **kwargs):
return {'name': 'pat'}
import ...
urlpatterns = patterns(
url(regex=r'^class_based_view/$',
view=my_app.views.SomeView.as_view(),
name='my_view'),
urlpatterns = patterns('',
url(regex=r'^$',
view=TemplateView.as_view(template_name='home.html'),
name='app.home'
),
Security
Basic login_required security can be set-up in urls.py:
from django.contrib.auth.decorators import login_required
url(regex=r'^private/$',
view=login_required(TemplateView.as_view(template_name='private.html')),
name='private'
),