Many models are tightly coupled to the default Django User
model (django.contrib.auth.models.User
).
Sometimes this user model just doesn't fit everyone's needs. By using UserForeignKey
it is possible to make the User
model configurable, encouraging loose coupling.
Additionally, this can help to prevent circular imports between User
and another model.
Use it like a standard ForeignKey
... it accepts all the same arguments.
If you want to use a User
model other than the default, just add USER_MODEL
to your settings file.... it uses dotted notation (app_label.model_name
).
Example:
class BlogPost(models.Model):
user = UserForeignKey(related_name="blog_posts")
title = models.CharField(...)
content = models.TextField(...)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | from django.db import models
from django.db.models import signals
from django.conf import settings
from django.dispatch import dispatcher
_USER_APP_NAME, _USER_MODEL_NAME = getattr(settings, 'USER_MODEL', 'auth.User').split('.') # We default to the django.contrib.auth.models.User model
_pending_user_lookups = []
__all__ = ['UserForeignKey',]
class UserForeignKey(models.ForeignKey):
def __init__(self, **kwargs):
self._stored_kwargs = kwargs
self.initialized = False
user_model = models.get_model(_USER_APP_NAME, _USER_MODEL_NAME, seed_cache=False)
if user_model is None:
_pending_user_lookups.append(self)
else:
self.__reinit__(user_model)
def __reinit__(self, to):
kwargs = self._stored_kwargs
kwargs['to'] = to
models.ForeignKey.__init__(self, **kwargs)
self.initialized = True
def contribute_to_class(self, cls, name):
if self.initialized:
models.ForeignKey.contribute_to_class(self, cls, name)
if hasattr(self, '_cached_contribute_to_class_args'):
del self._cached_contribute_to_class_args
else:
self._cached_contribute_to_class_args = (cls, name)
def do_user_lookup(sender):
if _USER_APP_NAME == sender._meta.app_label and _USER_MODEL_NAME == sender._meta.object_name:
for fk in _pending_user_lookups:
fk.__reinit__(sender)
fk.contribute_to_class(*fk._cached_contribute_to_class_args)
dispatcher.connect(do_user_lookup, signal=signals.class_prepared)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
Please login first before commenting.