head method on views for Django 1.3. Fixes #228

This commit is contained in:
Tom Christie 2012-09-27 13:34:28 +01:00
parent d2583b809c
commit 284a700e09

View File

@ -10,46 +10,17 @@ except ImportError:
import StringIO
# django.views.generic.View (Django >= 1.3)
try:
# First implementation of Django class-based views did not include head method
# in base View class - https://code.djangoproject.com/ticket/15668
if django.VERSION >= (1, 4):
from django.views.generic import View
if not hasattr(View, 'head'):
# First implementation of Django class-based views did not include head method
# in base View class - https://code.djangoproject.com/ticket/15668
class ViewPlusHead(View):
def head(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
View = ViewPlusHead
except ImportError:
from django import http
else:
from django.views.generic import View as _View
from django.utils.decorators import classonlymethod
from django.utils.functional import update_wrapper
# from django.utils.log import getLogger
# from django.utils.decorators import classonlymethod
# logger = getLogger('django.request') - We'll just drop support for logger if running Django <= 1.2
# Might be nice to fix this up sometime to allow rest_framework.compat.View to match 1.3's View more closely
class View(object):
"""
Intentionally simple parent class for all views. Only implements
dispatch-by-method and simple sanity checking.
"""
http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']
def __init__(self, **kwargs):
"""
Constructor. Called in the URLconf; can contain helpful extra
keyword arguments, and other things.
"""
# Go through keyword arguments, and either save their values to our
# instance, or raise an error.
for key, value in kwargs.iteritems():
setattr(self, key, value)
# @classonlymethod - We'll just us classmethod instead if running Django <= 1.2
@classmethod
class View(_View):
@classonlymethod
def as_view(cls, **initkwargs):
"""
Main entry point for a request-response process.
@ -66,6 +37,8 @@ except ImportError:
def view(request, *args, **kwargs):
self = cls(**initkwargs)
if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get
return self.dispatch(request, *args, **kwargs)
# take name and docstring from class
@ -76,32 +49,6 @@ except ImportError:
update_wrapper(view, cls.dispatch, assigned=())
return view
def dispatch(self, request, *args, **kwargs):
# Try to dispatch to the right method; if a method doesn't exist,
# defer to the error handler. Also defer to the error handler if the
# request method isn't on the approved list.
if request.method.lower() in self.http_method_names:
handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
else:
handler = self.http_method_not_allowed
self.request = request
self.args = args
self.kwargs = kwargs
return handler(request, *args, **kwargs)
def http_method_not_allowed(self, request, *args, **kwargs):
allowed_methods = [m for m in self.http_method_names if hasattr(self, m)]
#logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path),
# extra={
# 'status_code': 405,
# 'request': self.request
# }
#)
return http.HttpResponseNotAllowed(allowed_methods)
def head(self, request, *args, **kwargs):
return self.get(request, *args, **kwargs)
# PUT, DELETE do not require CSRF until 1.4. They should. Make it better.
if django.VERSION >= (1, 4):
from django.middleware.csrf import CsrfViewMiddleware