Permalink
Browse files

Lazy dict wrapper to void hitting the DB when not needed. Closes #387

  • Loading branch information...
1 parent f353288 commit 78670c422962c29479636ca1099faeda4501cc1e @omab committed Jul 9, 2012
Showing with 36 additions and 16 deletions.
  1. +22 −16 social_auth/context_processors.py
  2. +14 −0 social_auth/utils.py
@@ -2,7 +2,7 @@
from social_auth.models import UserSocialAuth
from social_auth.backends import get_backends
-from social_auth.utils import group_backend_by_type
+from social_auth.utils import group_backend_by_type, LazyDict
# Note: social_auth_backends, social_auth_by_type_backends and
# social_auth_by_name_backends don't play nice together.
@@ -12,20 +12,26 @@ def social_auth_backends(request):
"""Load Social Auth current user data to context.
Will add a output from backends_data to context under social_auth key.
"""
- return {'social_auth': backends_data(request.user)}
+ def context_value():
+ return backends_data(request.user)
+ return {'social_auth': LazyDict(context_value)}
def social_auth_by_type_backends(request):
"""Load Social Auth current user data to context.
Will add a output from backends_data to context under social_auth key where
each entry will be grouped by backend type (openid, oauth, oauth2).
"""
- data = backends_data(request.user)
- data['backends'] = group_backend_by_type(data['backends'])
- data['not_associated'] = group_backend_by_type(data['not_associated'])
- data['associated'] = group_backend_by_type(data['associated'],
- key=lambda assoc: assoc.provider)
- return {'social_auth': data}
+ def context_value():
+ data = backends_data(request.user)
+ data['backends'] = group_backend_by_type(data['backends'])
+ data['not_associated'] = group_backend_by_type(data['not_associated'])
+ data['associated'] = group_backend_by_type(
+ data['associated'],
+ key=lambda assoc: assoc.provider
+ )
+ return data
+ return {'social_auth': LazyDict(context_value)}
def social_auth_by_name_backends(request):
@@ -36,15 +42,15 @@ def social_auth_by_name_backends(request):
with a hyphen have the hyphen replaced with an underscore, e.g.
google-oauth2 becomes google_oauth2 when referenced in templates.
"""
- keys = get_backends().keys()
- accounts = dict(zip(keys, [None] * len(keys)))
- user = request.user
-
- if hasattr(user, 'is_authenticated') and user.is_authenticated():
- accounts.update((assoc.provider.replace('-', '_'), assoc)
+ def context_value():
+ keys = get_backends().keys()
+ accounts = dict(zip(keys, [None] * len(keys)))
+ user = request.user
+ if hasattr(user, 'is_authenticated') and user.is_authenticated():
+ accounts.update((assoc.provider.replace('-', '_'), assoc)
for assoc in UserSocialAuth.get_social_auth_for_user(user))
-
- return {'social_auth': accounts}
+ return accounts
+ return {'social_auth': LazyDict(context_value)}
def backends_data(user):
View
@@ -11,6 +11,7 @@
from django.conf import settings
from django.db.models import Model
from django.contrib.contenttypes.models import ContentType
+from django.utils.functional import SimpleLazyObject
try:
@@ -226,6 +227,19 @@ def url_add_parameters(url, params):
return url
+class LazyDict(SimpleLazyObject):
+ """Lazy dict initialization."""
+ def __getitem__(self, name):
+ if self._wrapped is None:
+ self._setup()
+ return self._wrapped[name]
+
+ def __setitem__(self, name, value):
+ if self._wrapped is None:
+ self._setup()
+ self._wrapped[name] = value
+
+
if __name__ == '__main__':
import doctest
doctest.testmod()

0 comments on commit 78670c4

Please sign in to comment.