Django 1.8+ extending the User model

前端 未结 3 1386
[愿得一人]
[愿得一人] 2021-01-24 07:21

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

3条回答
  •  臣服心动
    2021-01-24 07:44

    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.

提交回复
热议问题