Ticket #16963: relocate_view_class-2.diff
File relocate_view_class-2.diff, 13.8 KB (added by , 13 years ago) |
---|
-
new file django/views/base.py
diff --git a/django/views/base.py b/django/views/base.py new file mode 100644 index 0000000..924e0d4
- + 1 from functools import update_wrapper 2 3 from django import http 4 from django.utils.decorators import classonlymethod 5 from django.utils.log import getLogger 6 7 logger = getLogger('django.request') 8 9 class View(object): 10 """ 11 Intentionally simple parent class for all class-based views. Only 12 implements dispatch-by-method and simple sanity checking. 13 """ 14 15 http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace'] 16 17 def __init__(self, **kwargs): 18 """ 19 Constructor. Called in the URLconf; can contain helpful extra 20 keyword arguments, and other things. 21 """ 22 # Go through keyword arguments, and either save their values to our 23 # instance, or raise an error. 24 for key, value in kwargs.iteritems(): 25 setattr(self, key, value) 26 27 @classonlymethod 28 def as_view(cls, **initkwargs): 29 """ 30 Main entry point for a request-response process. 31 """ 32 # sanitize keyword arguments 33 for key in initkwargs: 34 if key in cls.http_method_names: 35 raise TypeError(u"You tried to pass in the %s method name as a " 36 u"keyword argument to %s(). Don't do that." 37 % (key, cls.__name__)) 38 if not hasattr(cls, key): 39 raise TypeError(u"%s() received an invalid keyword %r" % ( 40 cls.__name__, key)) 41 42 def view(request, *args, **kwargs): 43 self = cls(**initkwargs) 44 return self.dispatch(request, *args, **kwargs) 45 46 # take name and docstring from class 47 update_wrapper(view, cls, updated=()) 48 49 # and possible attributes set by decorators 50 # like csrf_exempt from dispatch 51 update_wrapper(view, cls.dispatch, assigned=()) 52 return view 53 54 def dispatch(self, request, *args, **kwargs): 55 # Try to dispatch to the right method; if a method doesn't exist, 56 # defer to the error handler. Also defer to the error handler if the 57 # request method isn't on the approved list. 58 if request.method.lower() in self.http_method_names: 59 handler = getattr(self, request.method.lower(), self.http_method_not_allowed) 60 else: 61 handler = self.http_method_not_allowed 62 self.request = request 63 self.args = args 64 self.kwargs = kwargs 65 return handler(request, *args, **kwargs) 66 67 def http_method_not_allowed(self, request, *args, **kwargs): 68 allowed_methods = [m for m in self.http_method_names if hasattr(self, m)] 69 logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path), 70 extra={ 71 'status_code': 405, 72 'request': self.request 73 } 74 ) 75 return http.HttpResponseNotAllowed(allowed_methods) 76 77 def head(self, *args, **kwargs): 78 return self.get(*args, **kwargs) 79 80 -
django/views/generic/__init__.py
diff --git a/django/views/generic/__init__.py b/django/views/generic/__init__.py index 1a98067..900d039 100644
a b 1 from django.views.generic.base import View, TemplateView, RedirectView 1 from django.views.base import View 2 from django.views.generic.base import TemplateView, RedirectView 2 3 from django.views.generic.dates import (ArchiveIndexView, YearArchiveView, MonthArchiveView, 3 4 WeekArchiveView, DayArchiveView, TodayArchiveView, 4 5 DateDetailView) -
django/views/generic/base.py
diff --git a/django/views/generic/base.py b/django/views/generic/base.py index f2d4950..90e321d 100644
a b 1 from functools import update_wrapper2 1 from django import http 3 2 from django.core.exceptions import ImproperlyConfigured 4 3 from django.template.response import TemplateResponse 5 4 from django.utils.log import getLogger 6 from django. utils.decorators import classonlymethod5 from django.views.base import View 7 6 8 7 logger = getLogger('django.request') 9 8 10 9 11 class View(object):12 """13 Intentionally simple parent class for all views. Only implements14 dispatch-by-method and simple sanity checking.15 """16 17 http_method_names = ['get', 'post', 'put', 'delete', 'head', 'options', 'trace']18 19 def __init__(self, **kwargs):20 """21 Constructor. Called in the URLconf; can contain helpful extra22 keyword arguments, and other things.23 """24 # Go through keyword arguments, and either save their values to our25 # instance, or raise an error.26 for key, value in kwargs.iteritems():27 setattr(self, key, value)28 29 @classonlymethod30 def as_view(cls, **initkwargs):31 """32 Main entry point for a request-response process.33 """34 # sanitize keyword arguments35 for key in initkwargs:36 if key in cls.http_method_names:37 raise TypeError(u"You tried to pass in the %s method name as a "38 u"keyword argument to %s(). Don't do that."39 % (key, cls.__name__))40 if not hasattr(cls, key):41 raise TypeError(u"%s() received an invalid keyword %r" % (42 cls.__name__, key))43 44 def view(request, *args, **kwargs):45 self = cls(**initkwargs)46 return self.dispatch(request, *args, **kwargs)47 48 # take name and docstring from class49 update_wrapper(view, cls, updated=())50 51 # and possible attributes set by decorators52 # like csrf_exempt from dispatch53 update_wrapper(view, cls.dispatch, assigned=())54 return view55 56 def dispatch(self, request, *args, **kwargs):57 # Try to dispatch to the right method; if a method doesn't exist,58 # defer to the error handler. Also defer to the error handler if the59 # request method isn't on the approved list.60 if request.method.lower() in self.http_method_names:61 handler = getattr(self, request.method.lower(), self.http_method_not_allowed)62 else:63 handler = self.http_method_not_allowed64 self.request = request65 self.args = args66 self.kwargs = kwargs67 return handler(request, *args, **kwargs)68 69 def http_method_not_allowed(self, request, *args, **kwargs):70 allowed_methods = [m for m in self.http_method_names if hasattr(self, m)]71 logger.warning('Method Not Allowed (%s): %s' % (request.method, request.path),72 extra={73 'status_code': 405,74 'request': self.request75 }76 )77 return http.HttpResponseNotAllowed(allowed_methods)78 79 def head(self, *args, **kwargs):80 return self.get(*args, **kwargs)81 82 83 10 class TemplateResponseMixin(object): 84 11 """ 85 12 A mixin that can be used to render a template. -
django/views/generic/dates.py
diff --git a/django/views/generic/dates.py b/django/views/generic/dates.py index c10db30..b9661fa 100644
a b from django.core.exceptions import ImproperlyConfigured 4 4 from django.http import Http404 5 5 from django.utils.encoding import force_unicode 6 6 from django.utils.translation import ugettext as _ 7 from django.views. generic.base import View7 from django.views.base import View 8 8 from django.views.generic.detail import BaseDetailView, SingleObjectTemplateResponseMixin 9 9 from django.views.generic.list import MultipleObjectMixin, MultipleObjectTemplateResponseMixin 10 10 -
django/views/generic/detail.py
diff --git a/django/views/generic/detail.py b/django/views/generic/detail.py index ab21573..eccbf2e 100644
a b from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist 2 2 from django.http import Http404 3 3 from django.utils.encoding import smart_str 4 4 from django.utils.translation import ugettext as _ 5 from django.views.generic.base import TemplateResponseMixin, View 5 from django.views.base import View 6 from django.views.generic.base import TemplateResponseMixin 6 7 7 8 8 9 class SingleObjectMixin(object): -
django/views/generic/edit.py
diff --git a/django/views/generic/edit.py b/django/views/generic/edit.py index 3cade52..4ab01d0 100644
a b 1 1 from django.forms import models as model_forms 2 2 from django.core.exceptions import ImproperlyConfigured 3 3 from django.http import HttpResponseRedirect 4 from django.views.generic.base import TemplateResponseMixin, View 4 from django.views.base import View 5 from django.views.generic.base import TemplateResponseMixin 5 6 from django.views.generic.detail import (SingleObjectMixin, 6 7 SingleObjectTemplateResponseMixin, BaseDetailView) 7 8 -
django/views/generic/list.py
diff --git a/django/views/generic/list.py b/django/views/generic/list.py index 9797356..6d04ac2 100644
a b from django.core.exceptions import ImproperlyConfigured 3 3 from django.http import Http404 4 4 from django.utils.encoding import smart_str 5 5 from django.utils.translation import ugettext as _ 6 from django.views.generic.base import TemplateResponseMixin, View 6 from django.views.base import View 7 from django.views.generic.base import TemplateResponseMixin 7 8 8 9 9 10 class MultipleObjectMixin(object): -
docs/ref/class-based-views.txt
diff --git a/docs/ref/class-based-views.txt b/docs/ref/class-based-views.txt index 5f1340b..4ec9cf5 100644
a b usable generic views. 41 41 For example, the :class:`~django.views.generic.base.detail.DetailView` 42 42 is composed from: 43 43 44 * :class:`~django. db.views.generic.base.View`, which provides the44 * :class:`~django.views.base.View`, which provides the 45 45 basic class-based behavior 46 * :class:`~django. db.views.generic.detail.SingleObjectMixin`, which46 * :class:`~django.views.generic.detail.SingleObjectMixin`, which 47 47 provides the utilities for retrieving and displaying a single object 48 * :class:`~django. db.views.generic.detail.SingleObjectTemplateResponseMixin`,48 * :class:`~django.views.generic.detail.SingleObjectTemplateResponseMixin`, 49 49 which provides the tools for rendering a single object into a 50 50 template-based response. 51 51 … … BaseDateListView 817 817 See :meth:`~django.db.models.query.QuerySet.dates()` for the 818 818 ways that the ``date_type`` argument can be used. 819 819 820 Class-based view base class 821 =========================== 820 822 821 Generic views 822 ============= 823 824 Simple generic views 825 -------------------- 826 827 .. currentmodule:: django.views.generic.base 823 .. currentmodule:: django.views.base 828 824 829 825 View 830 826 ~~~~ 831 827 .. class:: View() 832 828 833 The master class-based base view. All othergeneric class-based views829 The master class-based base view. All generic class-based views 834 830 inherit from this base class. 835 831 836 Each request served by a :class:`~django.views. generic.base.View` has an832 Each request served by a :class:`~django.views.base.View` has an 837 833 independent state; therefore, it is safe to store state variables on the 838 834 instance (i.e., ``self.foo = 3`` is a thread-safe operation). 839 835 … … View 879 875 The default implementation returns ``HttpResponseNotAllowed`` with list 880 876 of allowed methods in plain text. 881 877 878 Generic views 879 ============= 880 881 Simple generic views 882 -------------------- 883 884 .. currentmodule:: django.views.generic.base 885 882 886 TemplateView 883 887 ~~~~~~~~~~~~ 884 888 .. class:: TemplateView() -
docs/topics/class-based-views.txt
diff --git a/docs/topics/class-based-views.txt b/docs/topics/class-based-views.txt index 62368fa..e44ef57 100644
a b Decorating in URLconf 566 566 --------------------- 567 567 568 568 The simplest way of decorating class-based views is to decorate the 569 result of the :meth:`~django.views. generic.base.View.as_view` method.569 result of the :meth:`~django.views.base.View.as_view` method. 570 570 The easiest place to do this is in the URLconf where you deploy your 571 571 view:: 572 572 … … Decorating the class 589 589 590 590 To decorate every instance of a class-based view, you need to decorate 591 591 the class definition itself. To do this you apply the decorator to the 592 :meth:`~django.views. generic.base.View.dispatch` method of the class.592 :meth:`~django.views.base.View.dispatch` method of the class. 593 593 594 594 A method on a class isn't quite the same as a standalone function, so 595 595 you can't just apply a function decorator to the method -- you need to -
tests/regressiontests/generic_views/base.py
diff --git a/tests/regressiontests/generic_views/base.py b/tests/regressiontests/generic_views/base.py index 40490a4..58241e3 100644
a b import unittest 4 4 from django.core.exceptions import ImproperlyConfigured 5 5 from django.http import HttpResponse 6 6 from django.test import TestCase, RequestFactory 7 from django.views.generic import View, TemplateView, RedirectView 7 from django.views.base import View 8 from django.views.generic import TemplateView, RedirectView 8 9 9 10 10 11 class SimpleView(View): -
tests/regressiontests/special_headers/views.py
diff --git a/tests/regressiontests/special_headers/views.py b/tests/regressiontests/special_headers/views.py index ce94036..91a8b5b 100644
a b 1 1 # -*- coding:utf-8 -*- 2 2 from django.http import HttpResponse 3 3 from django.utils.decorators import decorator_from_middleware 4 from django.views. genericimport View4 from django.views.base import View 5 5 from django.middleware.doc import XViewMiddleware 6 6 7 7 xview_dec = decorator_from_middleware(XViewMiddleware)