Django Rest 自定义用户模型和身份验证问题

2025-06-08

Django Rest 自定义用户模型和身份验证

问题

我最近正在使用 Django rest + React 框架(顺便说一下,它很漂亮)为我的一位客户构建一个网站,但遇到了一个问题。

问题

如果你们当中有人使用过 Django Rest,你们就会知道在创建自定义用户模型时会出现多个问题,特别是所做的更改如何不会反映在保存中。

我将向您展示(在我看来)在 DRF(Django Rest Framework)中构建自定义用户模型的最佳方法,无需用户名。

步骤 1

创建一个名为 user 的应用程序(或者任何你想叫它的名字),并在 models.py 中创建一个扩展 AbstractBaseUser 的用户模型

    from django.db import models
    from django.contrib.auth.models import AbstractBaseUser,BaseUserManager
    import datetime

    class User(AbstractBaseUser):

        username = None
        email = models.EmailField(_('email address'), unique=True)
        name = models.CharField(max_length=100)
        date_of_birth = models.DateField(default=datetime.date.today)

        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = [ 'date_of_birth','name' ]

        def __str__(self):              # __unicode__ on Python 2
            return self.email

第 2 步

现在我们在模型中添加一条非常重要的线

    objects = UserManager()

这基本上告诉 Django 应该如何存储对象以及根据权限使用哪些属性。

步骤3

我们添加用户管理器

    class UserManager(BaseUserManager):

    use_in_migrations = True

    def create_user(self, email, name, date_of_birth, password=None):
        user = self.model(
            email=self.normalize_email(email),
            date_of_birth=date_of_birth,
            name=name,
        )
        user.set_password(password)
        user.save(using=self._db)
        return user

    def create_staffuser(self, email, name, date_of_birth, password):
        user = self.create_user(
            email,
            password=password,
            date_of_birth=date_of_birth,         
            name=name,
        )
        user.staff = True
        user.save(using=self._db)
        return user

    def create_superuser(self, email, name, date_of_birth, password):
        user = self.create_user(
            email,
            password=password,
            date_of_birth=date_of_birth,
            name= "True",
        )
        user.staff = True
        user.admin = True
        user.save(using=self._db)
        return user

步骤4

构建 CustomRegisterSerializer

    from rest_auth.registration.serializers import RegisterSerializer
    class CustomRegisterSerializer(RegisterSerializer):

        email = serializers.EmailField(required=True)
        password1 = serializers.CharField(write_only=True)
        name = serializers.CharField(required=True)
        date_of_birth = serializers.DateField(required=True)

        def get_cleaned_data(self):
            super(CustomRegisterSerializer, self).get_cleaned_data()

            return {
                'password1': self.validated_data.get('password1', ''),
                'email': self.validated_data.get('email', ''),
                'name': self.validated_data.get('name', ''),
                'date_of_birth': self.validated_data.get('date_of_birth', ''),
            }

    class CustomUserDetailsSerializer(serializers.ModelSerializer):

        class Meta:
            model = User
            fields = ('email','name','date_of_birth')
            read_only_fields = ('email',)

创建自定义视图,该视图仅包含所有用户对象作为查询集

    from rest_auth.registration.views import RegisterView

    class CustomRegisterView(RegisterView):
        queryset = User.objects.all()

最后更新 settings.py 以应用这些

ACCOUNT_USER_MODEL_USERNAME_FIELD = None
ACCOUNT_AUTHENTICATION_METHOD = 'email'

ACCOUNT_EMAIL_REQUIRED = True
ACCOUNT_UNIQUE_EMAIL = True
ACCOUNT_USERNAME_REQUIRED = False
ACCOUNT_USER_EMAIL_FIELD = 'email'
ACCOUNT_LOGOUT_ON_GET = True

AUTH_USER_MODEL = 'users.User'

REST_AUTH_SERIALIZERS = {
    "USER_DETAILS_SERIALIZER": "users.serializers.CustomUserDetailsSerializer",
}
REST_AUTH_REGISTER_SERIALIZERS = {
    "REGISTER_SERIALIZER": "users.serializers.CustomRegisterSerializer",
}

只需将视图添加到 URL 就可以了!

我真诚地相信 Django Rest + React 堆栈是目前游戏中最好的堆栈之一,但 Django Rest Framework 确实需要做更多的工作才能使其适合大多数开发人员。

如果你需要帮助,请联系我!或者你有一些项目需要人合作 :D

鏂囩珷鏉ユ簮锛�https://dev.to/callmetarush/the-django-rest-custom-user-model-and-authentication-5go9
PREV
#DevOps 新手指南 - Kubernetes 中的请求 x 限制
NEXT
⚙️ 使用 Prettier、AirBnB Styleguide、Husky 和 ​​lint-staged 将 Angular 应用迁移到 ESLint