1
1
# -*- coding: utf-8 -*-
2
2
from __future__ import with_statement
3
+ from contextlib import contextmanager
3
4
import inspect
4
5
import warnings
5
6
from cms .models .titlemodels import Title
@@ -132,45 +133,12 @@ def __call__(self, lang):
132
133
if view .namespace :
133
134
"%s:%s" % (view .namespace , view_name )
134
135
url = None
135
- # In Django < 1.7 reverse tries to convert
136
- # to string the arguments without checking
137
- # if they are classes or instances.
138
- # Here we monkeypatch the __unicode__ method
139
- # to make it works as static.
140
- # Before leaving we undo the monkeypatching
141
- if DJANGO_1_6 :
142
- for idx , arg in enumerate (view .args ):
143
- if inspect .isclass (arg ):
144
- if hasattr (arg , '__unicode__' ):
145
- @staticmethod
146
- def custom_str ():
147
- return six .text_type (arg )
148
- arg ._original = arg .__unicode__
149
- arg .__unicode__ = custom_str
150
- view .args [idx ] = arg
151
- for key , arg in view .kwargs .items ():
152
- if inspect .isclass (arg ):
153
- if hasattr (arg , '__unicode__' ):
154
- @staticmethod
155
- def custom_str ():
156
- return six .text_type (arg )
157
- arg ._original = arg .__unicode__
158
- arg .__unicode__ = custom_str
159
- view .kwargs [key ] = arg
160
136
with force_language (lang ):
161
- try :
162
- url = reverse (view_name , args = view .args , kwargs = view .kwargs , current_app = view .app_name )
163
- except NoReverseMatch :
164
- pass
165
- if DJANGO_1_6 :
166
- for idx , arg in enumerate (view .args ):
167
- if inspect .isclass (arg ):
168
- if hasattr (arg , '__unicode__' ):
169
- arg .__unicode__ = arg ._original
170
- for key , arg in view .kwargs .items ():
171
- if inspect .isclass (arg ):
172
- if hasattr (arg , '__unicode__' ):
173
- arg .__unicode__ = arg ._original
137
+ with static_stringifier (view ): # This is a fix for Django < 1.7
138
+ try :
139
+ url = reverse (view_name , args = view .args , kwargs = view .kwargs , current_app = view .app_name )
140
+ except NoReverseMatch :
141
+ pass
174
142
if url :
175
143
return url
176
144
return '%s%s' % (self .get_page_path (lang ), self .app_path )
@@ -187,3 +155,44 @@ def _wrapped(request, *args, **kwargs):
187
155
_wrapped .__name__ = func .__name__
188
156
_wrapped .__doc__ = func .__doc__
189
157
return _wrapped
158
+
159
+
160
+ @contextmanager
161
+ def static_stringifier (view ):
162
+ """
163
+ In Django < 1.7 reverse tries to convert to string the arguments without
164
+ checking whether they are classes or instances.
165
+
166
+ This context manager monkeypatches the __unicode__ method of each view
167
+ argument if it's a class definition to render it a static method.
168
+ Before leaving we undo the monkeypatching.
169
+ """
170
+ if DJANGO_1_6 :
171
+ for idx , arg in enumerate (view .args ):
172
+ if inspect .isclass (arg ):
173
+ if hasattr (arg , '__unicode__' ):
174
+ @staticmethod
175
+ def custom_str ():
176
+ return six .text_type (arg )
177
+ arg ._original = arg .__unicode__
178
+ arg .__unicode__ = custom_str
179
+ view .args [idx ] = arg
180
+ for key , arg in view .kwargs .items ():
181
+ if inspect .isclass (arg ):
182
+ if hasattr (arg , '__unicode__' ):
183
+ @staticmethod
184
+ def custom_str ():
185
+ return six .text_type (arg )
186
+ arg ._original = arg .__unicode__
187
+ arg .__unicode__ = custom_str
188
+ view .kwargs [key ] = arg
189
+ yield
190
+ if DJANGO_1_6 :
191
+ for idx , arg in enumerate (view .args ):
192
+ if inspect .isclass (arg ):
193
+ if hasattr (arg , '__unicode__' ):
194
+ arg .__unicode__ = arg ._original
195
+ for key , arg in view .kwargs .items ():
196
+ if inspect .isclass (arg ):
197
+ if hasattr (arg , '__unicode__' ):
198
+ arg .__unicode__ = arg ._original
0 commit comments