且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

扩展Django 1.11用户模型

更新时间:2023-12-01 12:32:52

这就是我扩展用户的方式模型。以下代码还将用户名替换为电子邮件字段。我发布它是因为它引起核心更改,因此可以弄清楚背后的逻辑。

This is how I extended my user model. The following code also substitutes the username for an email field. I am posting it because it causes core changes so it makes clear the logic behind.

可以在此帖子。也可以在

在这种情况下,AliasField创建字段 username 作为电子邮件。尽管鉴于django已记录了找到用户模型及其相关字段的正确方法

The AliasField in this case, creates the field username as an alias to email. Although this is not necessary given that django has documented the proper way of finding the user model and its relevant fields.

from django.contrib.auth.models import (
    AbstractBaseUser,
    PermissionsMixin,
    BaseUserManager,
)
from django.core.mail import send_mail
from django.db import models
from django.utils.translation import ugettext_lazy as _


class UserManager(BaseUserManager):
    def create_user(self, email, password=None, **kwargs):
        email = self.normalize_email(email)
        user = self.model(email=email, **kwargs)
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_superuser(self, **kwargs):
        user = self.create_user(**kwargs)
        user.is_superuser = True
        user.is_staff = True
        user.save(using=self._db)
        return user


class AliasField(models.Field):
    def contribute_to_class(self, cls, name, private_only=False):
        super().contribute_to_class(cls, name, private_only=True)
        setattr(cls, name, self)

    def __get__(self, instance, instance_type=None):
        return getattr(instance, self.db_column)


class MyUser(AbstractBaseUser, PermissionsMixin):
    custom_field = models.ForeignKey(
        'app.Model',
        on_delete=models.PROTECT,
    )

    email = models.EmailField(_('email address'), max_length=255, unique=True)

    is_staff = models.BooleanField(
        _('staff status'),
        default=False,
        help_text=_(
            'Designates whether the user can log into this admin '
            'site.'
        )
    )
    is_active = models.BooleanField(
        _('active'),
        default=True,
        help_text=_(
            'Designates whether this user should be treated as '
            'active. Unselect this instead of deleting accounts.'
        )
    )
    username = AliasField(db_column='email')

    objects = UserManager()

    USERNAME_FIELD = 'email'
    REQUIRED_FIELDS = ['user_branch_key', ]

    class Meta(object):
        ordering = ['email']
        verbose_name = _('My User')
        verbose_name_plural = _('My User')

    def __str__(self):
        return 'id: {0} - {1}, {2}'.format(self.id, self.email, self.user_branch_key)

    def get_full_name(self):
        return self.email

    def get_short_name(self):
        return self.email

    def email_user(self, subject, message, from_email=None, **kwargs):
        """
        Sends an email to this User.
        """
        send_mail(subject, message, from_email, [self.email], **kwargs)

一旦您扩展了用户模型,例如 ./ the_user / models.py 中名称为 the_user 的应用程序,您必须在 settings.py 文件:

Once you extend your user model, for example inside the application with the name the_user in the file ./the_user/models.py you have to make some changes in the settings.py file:


  • 中注册应用程序INSTALLED_APPS

  • ./ manage.py makemigrations && ./ manage.py迁移

  • 设置 AUTH_USER_MODEL ='the_user.MyUser 文档

  • Register the application in the INSTALLED_APPS
  • ./manage.py makemigrations && ./manage.py migrate
  • Set the AUTH_USER_MODEL = 'the_user.MyUser as described in the docs

这样,在另一个模型中,您可以如下添加外键:

This way, in another model you can add a foreignkey as follows:

from the_user.models import MyUser
from django.conf import settings
from django.db import models

class AModel(models.Model)
    user = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.PROTECT,
        related_name='%(app_label)s_%(class)s_user'
    )