Info: | Tools for Profile models in Django. |
---|---|
Version: | 0.2.1 |
Author: | Daniel Greenfeld (http://pydanny.com) |
- Lazy loading of your authenticated profile record across the request object lifetime. That means in the Python code and the templates.
- Name your profile model anything you want in settings.AUTH_PROFILE_MODULE.
Get the code:
pip install django-profiletools
Install the middleware and context_processor in your settings.py:
TEMPLATE_CONTEXT_PROCESSORS = ( ... 'profiletools.context_processors.fetch_profile', ) MIDDLEWARE_CLASSES = ( ... 'profiletools.middleware.LazyProfileMiddleware', )
Also in settings.py, set the AUTH_PROFILE_MODULE to your profile model:
AUTH_PROFILE_MODULE = "profiles.Profile"
Based on that, your profile model should resemble something like:
# profiles.models.Profile.py from django.contrib.auth.models import User from django.db import models class Profile(models.Model): user = models.OneToOneField(User) def __unicode__(self): return self.user.username
note: If you don't use profiles.models.Profile
, say members.models.UserProfile
go ahead and change the AUTH_PROFILE_MODULE
to "members.UserProfile".
In your templates:
{{ request.my_profile }}
In your functional views:
profile = request.my_profile
In your class-based views:
profile = self.request.my_profile
Call my_profile as many times as you want, it only loads once. So if you call it 100 times in a view, the SQL SELECT
is only done the first time. If no user is found then the my_profile call result is None
, which makes it easier to handle templates which need to be able to handle unauthenticated users (like the about page).
note: If you are using the members.UserProfile
example, you'll need to call that by using request.my_userprofile
.
If you use the is evaluation before doing anything else with the my_profile object, it will behave in a slightly unexpected manner:
The will always return false. For example:
>>> print(request.my_profile is None) False >>> p = request.user.get_profile() >>> print(request.my_profile is p) False
Also, the type built-in will return a django.utils.functional.SimpleLazyObject
object:
>>> print(type) <class 'django.utils.functional.SimpleLazyObject'>
Keep in mind what is placed in the my_profile
value is not a ModelClass
instance or None
object, but rather a django.utils.functional.SimpleLazyObject
.
How to evaluate the my_profile object
Use ==
to evaluate the my_profile object. This forces the object to be evaluated
and won't return frustrating false-positives.
The lazy loading of profiles was inspired by the rather incredible Noah Kantrowitz.