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
- get_object_or_none by azwdevops 1 month, 1 week ago
- Mask sensitive data from logger by agusmakmun 3 months ago
- Template tag - list punctuation for a list of items by shapiromatron 1 year, 5 months ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 1 year, 5 months ago
- Serializer factory with Django Rest Framework by julio 2 years ago
Comments
Please login first before commenting.