Ticket #6552: 6552_2.diff
File 6552_2.diff, 9.7 KB (added by , 15 years ago) |
---|
-
django/core/context_processors.py
diff -r 6490bd644de2 django/core/context_processors.py
a b 8 8 """ 9 9 10 10 from django.conf import settings 11 from django.template.utils import ContextLazyObject 12 from django.utils.functional import lazy, memoize 11 13 12 14 def auth(request): 13 15 """ … … 17 19 If there is no 'user' attribute in the request, uses AnonymousUser (from 18 20 django.contrib.auth). 19 21 """ 20 if hasattr(request, 'user'): 21 user = request.user 22 else: 23 from django.contrib.auth.models import AnonymousUser 24 user = AnonymousUser() 22 # If we access request.user, request.session is accessed, which results in 23 # 'Vary: Cookie' being sent in every request that uses this context 24 # processor, which can easily be every request on a site if 25 # TEMPLATE_CONTEXT_PROCESSORS has this context processor added. This kills 26 # the ability to cache. So, we carefully ensure these attributes are lazy. 27 # We don't use django.utils.functional.lazy() for User, because that 28 # requires knowing the class of the object we want to proxy, which could 29 # break with custom auth backends. LazyObject is a less complete but more 30 # flexible solution that is a good enough wrapper for 'User'. 31 def get_user(): 32 if hasattr(request, 'user'): 33 return request.user 34 else: 35 from django.contrib.auth.models import AnonymousUser 36 return AnonymousUser() 37 25 38 return { 26 'user': user,27 'messages': user.get_and_delete_messages(),28 'perms': PermWrapper(user),39 'user': ContextLazyObject(get_user), 40 'messages': lazy(memoize(lambda: get_user().get_and_delete_messages(), {}, 0), list)(), 41 'perms': lazy(lambda: PermWrapper(get_user()), PermWrapper)(), 29 42 } 30 43 31 44 def debug(request): … … 79 92 80 93 def __getitem__(self, module_name): 81 94 return PermLookupDict(self.user, module_name) 82 95 83 96 def __iter__(self): 84 97 # I am large, I contain multitudes. 85 98 raise TypeError("PermWrapper is not iterable.") -
new file django/template/utils.py
diff -r 6490bd644de2 django/template/utils.py
- + 1 from django.utils.functional import LazyObject 2 3 class ContextLazyObject(LazyObject): 4 """ 5 A lazy object initialised from any function, useful for lazily 6 adding things to the Context. 7 8 Works best for compound objects of unknown type where you are only 9 interested in the attributes, and won't need things like str(obj). For 10 simple objects of known type, use django.utils.functional.lazy 11 12 For sequences, use a generator instead. 13 """ 14 def __init__(self, func): 15 """ 16 Pass in a callable that returns the actual value to be used 17 """ 18 self.__dict__['_setupfunc'] = func 19 # For some reason, we have to inline LazyObject.__init__ here to avoid 20 # recursion 21 self._wrapped = None 22 23 def _setup(self): 24 self._wrapped = self._setupfunc() -
new file tests/regressiontests/context_processors/fixtures/context-processors-users.xml
diff -r 6490bd644de2 tests/regressiontests/context_processors/fixtures/context-processors-users.xml
- + 1 <?xml version="1.0" encoding="utf-8"?> 2 <django-objects version="1.0"> 3 <object pk="100" model="auth.user"> 4 <field type="CharField" name="username">super</field> 5 <field type="CharField" name="first_name">Super</field> 6 <field type="CharField" name="last_name">User</field> 7 <field type="CharField" name="email">super@example.com</field> 8 <field type="CharField" name="password">sha1$995a3$6011485ea3834267d719b4c801409b8b1ddd0158</field> 9 <field type="BooleanField" name="is_staff">True</field> 10 <field type="BooleanField" name="is_active">True</field> 11 <field type="BooleanField" name="is_superuser">True</field> 12 <field type="DateTimeField" name="last_login">2007-05-30 13:20:10</field> 13 <field type="DateTimeField" name="date_joined">2007-05-30 13:20:10</field> 14 <field to="auth.group" name="groups" rel="ManyToManyRel"></field> 15 <field to="auth.permission" name="user_permissions" rel="ManyToManyRel"></field> 16 </object> 17 </django-objects> -
new file tests/regressiontests/context_processors/templates/context_processors/auth_attrs_access.html
diff -r 6490bd644de2 tests/regressiontests/context_processors/templates/context_processors/auth_attrs_access.html
- + 1 {{ user.id }} -
new file tests/regressiontests/context_processors/templates/context_processors/auth_attrs_messages.html
diff -r 6490bd644de2 tests/regressiontests/context_processors/templates/context_processors/auth_attrs_messages.html
- + 1 {% for m in messages %}{{ m }}{% endfor %} -
new file tests/regressiontests/context_processors/templates/context_processors/auth_attrs_perms.html
diff -r 6490bd644de2 tests/regressiontests/context_processors/templates/context_processors/auth_attrs_perms.html
- + 1 {% if perms.auth %}Has auth permissions{% endif %} -
new file tests/regressiontests/context_processors/templates/context_processors/auth_attrs_test_access.html
diff -r 6490bd644de2 tests/regressiontests/context_processors/templates/context_processors/auth_attrs_test_access.html
- + 1 {% if session_accessed %}Session accessed{% else %}Session not accessed{% endif %} -
tests/regressiontests/context_processors/tests.py
diff -r 6490bd644de2 tests/regressiontests/context_processors/tests.py
a b 36 36 self.assertContains(response, url) 37 37 response = self.client.post(url, {'path': '/blah/'}) 38 38 self.assertContains(response, url) 39 40 class AuthContextProcessorTests(TestCase): 41 """ 42 Tests for the ``django.core.context_processors.auth`` processor 43 """ 44 urls = 'regressiontests.context_processors.urls' 45 fixtures = ['context-processors-users.xml'] 46 47 def test_session_not_accessed(self): 48 """ 49 Tests that the session is not accessed simply by including 50 the auth context processor 51 """ 52 response = self.client.get('/auth_processor_no_attr_access/') 53 self.assertContains(response, "Session not accessed") 54 55 def test_session_is_accessed(self): 56 """ 57 Tests that the session is accessed if the auth context processor 58 is used and relevant attributes accessed. 59 """ 60 response = self.client.get('/auth_processor_attr_access/') 61 self.assertContains(response, "Session accessed") 62 63 def test_perms_attrs(self): 64 self.client.login(username='super', password='secret') 65 response = self.client.get('/auth_processor_perms/') 66 self.assertContains(response, "Has auth permissions") 67 68 def test_message_attrs(self): 69 self.client.login(username='super', password='secret') 70 response = self.client.get('/auth_processor_messages/') 71 self.assertContains(response, "Message 1") 72 -
tests/regressiontests/context_processors/urls.py
diff -r 6490bd644de2 tests/regressiontests/context_processors/urls.py
a b 5 5 6 6 urlpatterns = patterns('', 7 7 (r'^request_attrs/$', views.request_processor), 8 (r'^auth_processor_no_attr_access/$', views.auth_processor_no_attr_access), 9 (r'^auth_processor_attr_access/$', views.auth_processor_attr_access), 10 (r'^auth_processor_perms/$', views.auth_processor_perms), 11 (r'^auth_processor_messages/$', views.auth_processor_messages), 8 12 ) -
tests/regressiontests/context_processors/views.py
diff -r 6490bd644de2 tests/regressiontests/context_processors/views.py
a b 6 6 def request_processor(request): 7 7 return render_to_response('context_processors/request_attrs.html', 8 8 RequestContext(request, {}, processors=[context_processors.request])) 9 10 def auth_processor_no_attr_access(request): 11 r1 = render_to_response('context_processors/auth_attrs_no_access.html', 12 RequestContext(request, {}, processors=[context_processors.auth])) 13 # *After* rendering, we check whether the session was accessed 14 return render_to_response('context_processors/auth_attrs_test_access.html', 15 {'session_accessed':request.session.accessed}) 16 17 def auth_processor_attr_access(request): 18 r1 = render_to_response('context_processors/auth_attrs_access.html', 19 RequestContext(request, {}, processors=[context_processors.auth])) 20 return render_to_response('context_processors/auth_attrs_test_access.html', 21 {'session_accessed':request.session.accessed}) 22 23 def auth_processor_perms(request): 24 return render_to_response('context_processors/auth_attrs_perms.html', 25 RequestContext(request, {}, processors=[context_processors.auth])) 26 27 def auth_processor_messages(request): 28 request.user.message_set.create(message="Message 1") 29 return render_to_response('context_processors/auth_attrs_messages.html', 30 RequestContext(request, {}, processors=[context_processors.auth]))