I know this question has been asked hundreds of times, but most of them contain -accepted- answers that are not valid anymore. Some of them are for Django 1.5, some of them are
An article about the topic: How to Extend Django User Model
What I use is the One-To-One
approach:
class UserProfile(models.Model):
user = models.OneToOneField(User, related_name="profile")
#more fields
@staticmethod
@receiver(post_save, sender=User, dispatch_uid="at_user_post_save")
def user_post_save(sender, instance, **kwargs):
#create new profile on user.save() (if necessary)
profile, new = UserProfile.objects.get_or_create(user=instance)
#in view
profile = request.user.profile
UPDATE:
Are there any other caveats? Like what happens when I remove a UserProfile?
UserProfile
is the one who holds the relation, so on delete no user
should be deleted. You can control what must be the behavior when a user
gets deleted via the on_delete kwarg.
Also do they always have the same private keys?
No each class have its own PKs, just the UserProfile
holds the PK to its user
.
OneToOneField
is in conceptually a ForeignKey
with an unique=True
, the big difference is that the reverse side of the relation do not return a list with 0/1 elements, but the element itself or raise DoesNotExist
or None
if null=True
.
The only thing which I don't like in this approach is that you always have to do 1 more query to get user.profile
. I still can't find a good and clean approach to always .select_related('profile')
when a new user
is fetched from auth
, but this is more of a problem of the authentication system rather than the approach itself.