Skip to content
Projeler
Gruplar
Parçacıklar
Yardım
Yükleniyor...
Oturum aç / Kaydol
Gezinmeyi değiştir
D
django
Proje
Proje
Ayrıntılar
Etkinlik
Cycle Analytics
Depo (repository)
Depo (repository)
Dosyalar
Kayıtlar (commit)
Dallar (branch)
Etiketler
Katkıda bulunanlar
Grafik
Karşılaştır
Grafikler
Konular (issue)
0
Konular (issue)
0
Liste
Pano
Etiketler
Kilometre Taşları
Birleştirme (merge) Talepleri
0
Birleştirme (merge) Talepleri
0
CI / CD
CI / CD
İş akışları (pipeline)
İşler
Zamanlamalar
Grafikler
Paketler
Paketler
Wiki
Wiki
Parçacıklar
Parçacıklar
Üyeler
Üyeler
Collapse sidebar
Close sidebar
Etkinlik
Grafik
Grafikler
Yeni bir konu (issue) oluştur
İşler
Kayıtlar (commit)
Konu (issue) Panoları
Kenar çubuğunu aç
Batuhan Osman TASKAYA
django
Commits
3bdaaf67
Kaydet (Commit)
3bdaaf67
authored
Tem 21, 2015
tarafından
Rigel Di Scala
Kaydeden (comit)
Tim Graham
Agu 01, 2015
Dosyalara gözat
Seçenekler
Dosyalara Gözat
İndir
Eposta Yamaları
Sade Fark
Fixed #25146 -- Allowed method_decorator() to decorate classes.
üst
1a76257b
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
102 additions
and
9 deletions
+102
-9
decorators.py
django/utils/decorators.py
+29
-4
utils.txt
docs/ref/utils.txt
+8
-2
1.9.txt
docs/releases/1.9.txt
+3
-0
intro.txt
docs/topics/class-based-views/intro.txt
+12
-2
tests.py
tests/decorators/tests.py
+50
-1
No files found.
django/utils/decorators.py
Dosyayı görüntüle @
3bdaaf67
...
@@ -17,13 +17,34 @@ class classonlymethod(classmethod):
...
@@ -17,13 +17,34 @@ class classonlymethod(classmethod):
return
super
(
classonlymethod
,
self
)
.
__get__
(
instance
,
owner
)
return
super
(
classonlymethod
,
self
)
.
__get__
(
instance
,
owner
)
def
method_decorator
(
decorator
):
def
method_decorator
(
decorator
,
name
=
''
):
"""
"""
Converts a function decorator into a method decorator
Converts a function decorator into a method decorator
"""
"""
# 'func' is a function at the time it is passed to _dec, but will eventually
# 'obj' can be a class or a function. If 'obj' is a function at the time it
# be a method of the class it is defined on.
# is passed to _dec, it will eventually be a method of the class it is
def
_dec
(
func
):
# defined on. If 'obj' is a class, the 'name' is required to be the name
# of the method that will be decorated.
def
_dec
(
obj
):
is_class
=
isinstance
(
obj
,
type
)
if
is_class
:
if
name
and
hasattr
(
obj
,
name
):
func
=
getattr
(
obj
,
name
)
if
not
callable
(
func
):
raise
TypeError
(
"Cannot decorate '{0}' as it isn't a callable "
"attribute of {1} ({2})"
.
format
(
name
,
obj
,
func
)
)
else
:
raise
ValueError
(
"The keyword argument `name` must be the name of a method "
"of the decorated class: {0}. Got '{1}' instead"
.
format
(
obj
,
name
,
)
)
else
:
func
=
obj
def
_wrapper
(
self
,
*
args
,
**
kwargs
):
def
_wrapper
(
self
,
*
args
,
**
kwargs
):
@decorator
@decorator
def
bound_func
(
*
args2
,
**
kwargs2
):
def
bound_func
(
*
args2
,
**
kwargs2
):
...
@@ -43,6 +64,10 @@ def method_decorator(decorator):
...
@@ -43,6 +64,10 @@ def method_decorator(decorator):
# Need to preserve any existing attributes of 'func', including the name.
# Need to preserve any existing attributes of 'func', including the name.
update_wrapper
(
_wrapper
,
func
)
update_wrapper
(
_wrapper
,
func
)
if
is_class
:
setattr
(
obj
,
name
,
_wrapper
)
return
obj
return
_wrapper
return
_wrapper
update_wrapper
(
_dec
,
decorator
,
assigned
=
available_attrs
(
decorator
))
update_wrapper
(
_dec
,
decorator
,
assigned
=
available_attrs
(
decorator
))
...
...
docs/ref/utils.txt
Dosyayı görüntüle @
3bdaaf67
...
@@ -151,11 +151,17 @@ The functions defined in this module share the following properties:
...
@@ -151,11 +151,17 @@ The functions defined in this module share the following properties:
.. module:: django.utils.decorators
.. module:: django.utils.decorators
:synopsis: Functions that help with creating decorators for views.
:synopsis: Functions that help with creating decorators for views.
.. function:: method_decorator(decorator)
.. function:: method_decorator(decorator
, name=''
)
Converts a function decorator into a method decorator. See :ref:`decorating
Converts a function decorator into a method decorator. It can be used to
decorate methods or classes; in the latter case, ``name`` is the name
of the method to be decorated and is required. See :ref:`decorating
class based views<decorating-class-based-views>` for example usage.
class based views<decorating-class-based-views>` for example usage.
.. versionchanged:: 1.9
The ability to decorate classes and the ``name`` parameter were added.
.. function:: decorator_from_middleware(middleware_class)
.. function:: decorator_from_middleware(middleware_class)
Given a middleware class, returns a view decorator. This lets you use
Given a middleware class, returns a view decorator. This lets you use
...
...
docs/releases/1.9.txt
Dosyayı görüntüle @
3bdaaf67
...
@@ -338,6 +338,9 @@ Generic Views
...
@@ -338,6 +338,9 @@ Generic Views
* Class based views generated using ``as_view()`` now have ``view_class``
* Class based views generated using ``as_view()`` now have ``view_class``
and ``view_initkwargs`` attributes.
and ``view_initkwargs`` attributes.
* :func:`~django.utils.decorators.method_decorator` can now be used to
:ref:`decorate classes instead of methods <decorating-class-based-views>`.
Internationalization
Internationalization
^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^
...
...
docs/topics/class-based-views/intro.txt
Dosyayı görüntüle @
3bdaaf67
...
@@ -279,8 +279,18 @@ that it can be used on an instance method. For example::
...
@@ -279,8 +279,18 @@ that it can be used on an instance method. For example::
def dispatch(self, *args, **kwargs):
def dispatch(self, *args, **kwargs):
return super(ProtectedView, self).dispatch(*args, **kwargs)
return super(ProtectedView, self).dispatch(*args, **kwargs)
In this example, every instance of ``ProtectedView`` will have
Or, more succinctly, you can decorate the class instead and pass the name
login protection.
of the method to be decorated as the keyword argument ``name``::
@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'
.. versionchanged:: 1.9
The ability to use ``method_decorator()`` on a class was added.
In this example, every instance of ``ProtectedView`` will have login protection.
.. note::
.. note::
...
...
tests/decorators/tests.py
Dosyayı görüntüle @
3bdaaf67
...
@@ -7,6 +7,7 @@ from django.contrib.auth.decorators import (
...
@@ -7,6 +7,7 @@ from django.contrib.auth.decorators import (
)
)
from
django.http
import
HttpRequest
,
HttpResponse
,
HttpResponseNotAllowed
from
django.http
import
HttpRequest
,
HttpResponse
,
HttpResponseNotAllowed
from
django.middleware.clickjacking
import
XFrameOptionsMiddleware
from
django.middleware.clickjacking
import
XFrameOptionsMiddleware
from
django.test
import
SimpleTestCase
from
django.utils.decorators
import
method_decorator
from
django.utils.decorators
import
method_decorator
from
django.utils.functional
import
allow_lazy
,
lazy
from
django.utils.functional
import
allow_lazy
,
lazy
from
django.views.decorators.cache
import
(
from
django.views.decorators.cache
import
(
...
@@ -189,7 +190,7 @@ class ClsDec(object):
...
@@ -189,7 +190,7 @@ class ClsDec(object):
return
update_wrapper
(
wrapped
,
f
)
return
update_wrapper
(
wrapped
,
f
)
class
MethodDecoratorTests
(
TestCase
):
class
MethodDecoratorTests
(
Simple
TestCase
):
"""
"""
Tests for method_decorator
Tests for method_decorator
"""
"""
...
@@ -274,6 +275,54 @@ class MethodDecoratorTests(TestCase):
...
@@ -274,6 +275,54 @@ class MethodDecoratorTests(TestCase):
self
.
assertEqual
(
Test
()
.
method
(
1
),
1
)
self
.
assertEqual
(
Test
()
.
method
(
1
),
1
)
def
test_class_decoration
(
self
):
"""
@method_decorator can be used to decorate a class and its methods.
"""
def
deco
(
func
):
def
_wrapper
(
*
args
,
**
kwargs
):
return
True
return
_wrapper
@method_decorator
(
deco
,
name
=
"method"
)
class
Test
(
object
):
def
method
(
self
):
return
False
self
.
assertTrue
(
Test
()
.
method
())
def
test_invalid_non_callable_attribute_decoration
(
self
):
"""
@method_decorator on a non-callable attribute raises an error.
"""
msg
=
(
"Cannot decorate 'prop' as it isn't a callable attribute of "
"<class 'Test'> (1)"
)
with
self
.
assertRaisesMessage
(
TypeError
,
msg
):
@method_decorator
(
lambda
:
None
,
name
=
"prop"
)
class
Test
(
object
):
prop
=
1
@classmethod
def
__module__
(
cls
):
return
"tests"
def
test_invalid_method_name_to_decorate
(
self
):
"""
@method_decorator on a nonexistent method raises an error.
"""
msg
=
(
"The keyword argument `name` must be the name of a method of the "
"decorated class: <class 'Test'>. Got 'non_existing_method' instead"
)
with
self
.
assertRaisesMessage
(
ValueError
,
msg
):
@method_decorator
(
lambda
:
None
,
name
=
"non_existing_method"
)
class
Test
(
object
):
@classmethod
def
__module__
(
cls
):
return
"tests"
class
XFrameOptionsDecoratorsTests
(
TestCase
):
class
XFrameOptionsDecoratorsTests
(
TestCase
):
"""
"""
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment