Django: Why create a OneToOne to UserProfile instead of subclassing auth.User?

后端 未结 3 1265
梦毁少年i
梦毁少年i 2020-12-05 16:38

Note: If you are tempted to \'answer\' this question by telling me that you don\'t like django.contrib.auth, please move on. That will not be helpful. I am well aware of t

3条回答
  •  误落风尘
    2020-12-05 17:09

    Is it more efficient and effective to inherit the User model? I don't see why, but I'd like to read your arguments. IMNSHO, model inheritance has always been a pain.

    Yet, this may not answer your question, but I'm quite satisfied with the solution proposed by Will Hardy in this snippet. By taking advantage of signals, it automatically creates a new user profile for every new user.

    The link is unlikely to disappear, but here's my slightly different version of his code:

    from django.contrib.auth.models import User
    from django.db import models
    from django.db.models.signals import post_save
    from django.utils.translation import ugettext_lazy as _
    
    class AuthUserProfileModelBase(models.base.ModelBase):
        # _prepare is not part of the public API and may change
        def _prepare(self):
            super(AuthUserProfileModelBase, self)._prepare()
            def on_save(sender, instance, created, **kwargs):
                if created:
                    self.objects.create(user=instance)
            # Automatically link profile when a new user is created
            post_save.connect(on_save, sender=User, weak=False)
    
    # Every profile model must inherit this class
    class AuthUserProfileModel(models.Model):
        class Meta:
            abstract = True
        __metaclass__ = AuthUserProfileModelBase
        user = models.OneToOneField(User, db_column='auth_user_id',
            primary_key=True, parent_link=True)
    
    # The actual profile model
    class Profile(AuthUserProfileModel):
        class Meta:
            app_label = 'some_app_label'
            db_table = 'auth_user_profile'
            managed = True
        language = models.CharField(_('language'), max_length=5, default='en')
    

    Of course, any credit goes to Will Hardy.

提交回复
热议问题