From 36686cad13e7483699f224b16c9b7722c969f355 Mon Sep 17 00:00:00 2001 From: Max Arnold Date: Thu, 12 Jul 2012 22:40:24 +0700 Subject: [PATCH 1/3] add View.head() method at runtime (should fix AttributeError: object has no attribute 'get') --- djangorestframework/compat.py | 35 +++++++++++++++++++++++++++++++++-- 1 file changed, 33 insertions(+), 2 deletions(-) diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index 83d26f1ff..11f24b867 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -68,12 +68,41 @@ except ImportError: # django.views.generic.View (Django >= 1.3) try: from django.views.generic import View + from django.utils.decorators import classonlymethod + from django.utils.functional import update_wrapper + 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) + @classonlymethod + def as_view(cls, **initkwargs): + """ + Main entry point for a request-response process. + """ + # sanitize keyword arguments + for key in initkwargs: + if key in cls.http_method_names: + raise TypeError(u"You tried to pass in the %s method name as a " + u"keyword argument to %s(). Don't do that." + % (key, cls.__name__)) + if not hasattr(cls, key): + raise TypeError(u"%s() received an invalid keyword %r" % ( + cls.__name__, key)) + + 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 + update_wrapper(view, cls, updated=()) + + # and possible attributes set by decorators + # like csrf_exempt from dispatch + update_wrapper(view, cls.dispatch, assigned=()) + return view View = ViewPlusHead except ImportError: @@ -121,6 +150,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 From fe262ef3537fa67ecda374825a295ff854f027a3 Mon Sep 17 00:00:00 2001 From: Max Arnold Date: Thu, 12 Jul 2012 23:12:09 +0700 Subject: [PATCH 2/3] patch View.head() only for django < 1.4 --- djangorestframework/compat.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index 11f24b867..b5858a826 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -65,13 +65,14 @@ except ImportError: environ.update(request) return WSGIRequest(environ) -# django.views.generic.View (Django >= 1.3) +# django.views.generic.View (1.3 <= Django < 1.4) try: from django.views.generic import View - from django.utils.decorators import classonlymethod - from django.utils.functional import update_wrapper - if not hasattr(View, 'head'): + if django.VERSION < (1, 4): + from django.utils.decorators import classonlymethod + from django.utils.functional import update_wrapper + # 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): From 650c04662dc4b47f285601fefad3b71afc7f6461 Mon Sep 17 00:00:00 2001 From: Max Arnold Date: Thu, 12 Jul 2012 23:13:04 +0700 Subject: [PATCH 3/3] remove remaining head() method --- djangorestframework/compat.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/djangorestframework/compat.py b/djangorestframework/compat.py index b5858a826..b86810223 100644 --- a/djangorestframework/compat.py +++ b/djangorestframework/compat.py @@ -186,9 +186,6 @@ except ImportError: #) 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