如何在Django User模型添加自定义字段并支持React对接?
Django 自定义用户字段实现及前后端对接方案
一、扩展Django User模型添加自定义字段
Django官方不推荐直接修改内置User模型,优先使用继承AbstractUser的方式扩展自定义字段,性能优于外键关联的扩展方式,步骤如下:
- 在用户模块(通常命名为
accounts)的models.py中定义自定义用户模型,覆盖/新增所需字段:
from django.contrib.auth.models import AbstractUser from django.db import models class CustomUser(AbstractUser): # 覆盖内置邮箱字段,设置为唯一必填项 email = models.EmailField(unique=True, blank=False) # 新增手机号字段,按国内手机号长度设置规则 phone = models.CharField(max_length=11, unique=True, blank=False, verbose_name="手机号") # 新增是否拥有PC字段,默认值为否 has_pc = models.BooleanField(default=False, verbose_name="是否拥有PC设备") # 新增新闻通讯订阅字段,默认值为订阅 subscribe_newsletter = models.BooleanField(default=True, verbose_name="是否订阅新闻通讯") # 指定创建超级管理员时必须填写的字段 REQUIRED_FIELDS = ["email", "phone"]
- 在项目
settings.py中指定全局使用的用户模型,该配置必须在第一次执行数据库迁移前添加,否则会出现表结构冲突:
# settings.py AUTH_USER_MODEL = "accounts.CustomUser"
- 执行
python manage.py makemigrations和python manage.py migrate完成数据库表创建。
注意:密码确认项不需要写入模型层,该字段仅用于注册环节的输入校验,不需要持久化存储到数据库,后续在接口校验环节处理即可。
如果项目已经完成过初始数据库迁移,不想清库重建,可以用一对一外键关联内置User模型的方式存储扩展字段,示例:
from django.contrib.auth.models import User from django.db import models class UserProfile(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE, related_name="profile") phone = models.CharField(max_length=11, unique=True, blank=False) has_pc = models.BooleanField(default=False) subscribe_newsletter = models.BooleanField(default=True)
二、React前端对接方案
前后端分离场景下,优先使用Django REST Framework(简称DRF)构建标准JSON接口供React调用,步骤如下:
- 编写注册接口的序列化器,在这里完成密码一致性校验:
# accounts/serializers.py from rest_framework import serializers from .models import CustomUser class UserRegisterSerializer(serializers.ModelSerializer): # 新增密码确认字段,仅允许写入不返回给前端 password_confirm = serializers.CharField(write_only=True, required=True, style={"input_type": "password"}) class Meta: model = CustomUser fields = ["username", "email", "phone", "password", "password_confirm", "has_pc", "subscribe_newsletter"] # 密码字段设置为仅写入,避免接口返回密码密文 extra_kwargs = {"password": {"write_only": True}} def validate(self, attrs): # 校验两次输入密码是否一致 if attrs["password"] != attrs["password_confirm"]: raise serializers.ValidationError({"password_confirm": "两次输入的密码不一致"}) return attrs def create(self, validated_data): # 移除不需要入库的密码确认字段 validated_data.pop("password_confirm") # 调用Django内置的create_user方法创建用户,自动完成密码加密 user = CustomUser.objects.create_user(**validated_data) return user
- 编写对应注册视图、配置接口路由后,React端可以直接通过axios/fetch调用注册接口,按接口要求传入JSON格式参数,接收返回的成功/错误状态做对应交互即可。
- 如果不想手动编写认证相关接口,可以直接使用成熟的DRF认证扩展,注册时只需要在配置中声明新增的自定义字段,即可自动生成注册、登录、密码找回等全套标准接口,前端直接对接即可,减少重复开发工作量。
开发注意事项:所有接口需要配置跨域允许规则,否则React本地调试时会被浏览器跨域策略拦截,安装对应跨域中间件添加配置即可解决。
内容的提问来源于stack exchange,提问作者omar shokry
相关产品推荐
相关产品推荐

