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'
),