Django使用auth_user表构建一对多/多对多关联的实现方法
Django 一对多/多对多关系关联用户表方案说明
实践合理性与可行性判断
- 该实现思路不属于不良实践,反而属于Django官方推荐的自定义用户模型标准实现方案,完全具备可实现性,适配你仅通过Django Admin交付功能、仅需编写模型层代码的场景。
- 你当前采用继承
AbstractUser替换默认用户表的方式,比直接外键关联原生auth_user表灵活性更高:后续如果需要给教师角色新增专属字段,直接在Teacher模型上添加即可,不需要额外做一对一关联表查询,长期维护成本更低。 - 唯一需要注意的约束:
AUTH_USER_MODEL配置必须在项目第一次执行数据库迁移前完成添加,项目已经生成过迁移文件、上线运行后不建议随意更换用户模型,否则会导致外键关联失效、数据错乱问题。你当前重置数据库、清理历史迁移文件的操作,就是为了规避初始化阶段的配置冲突,操作逻辑正确。
具体实现步骤
1. 编写模型层代码
在对应app的models.py中写入如下代码:
from django.db import models from django.contrib.auth.models import AbstractUser class Profile(models.Model): profile_name = models.CharField(max_length=100) profile_url = models.URLField(max_length=255) def __str__(self): return self.profile_name class Teacher(AbstractUser): profile = models.ManyToManyField(Profile, through='TeacherProfile') def __str__(self): return self.email class TeacherProfile(models.Model): teacher = models.ForeignKey(Teacher, on_delete=models.CASCADE) profile = models.ForeignKey(Profile, on_delete=models.CASCADE) profile_url = models.URLField(max_length=255) class Meta: unique_together = (('teacher', 'profile'),) def __str__(self): return f'{self.teacher}, {self.profile}'
2. 修改项目配置
在项目的settings.py中添加配置,指定自定义用户模型:
AUTH_USER_MODEL = 'vcm.Teacher'
注意:将
vcm替换为你存放Teacher模型的对应app名。
3. 执行迁移操作
如果是全新未初始化的项目,直接执行迁移、创建超级用户命令即可:
python3 manage.py makemigrations python3 manage.py migrate python3 manage.py createsuperuser
如果是之前已经执行过迁移、生成过默认auth_user表的开发环境,需要先清理旧数据与迁移文件再执行初始化:
# 注意:以下操作会清空所有数据库数据,禁止在生产环境执行 drop database vcm; create database vcm; find . -path "*/migrations/*.py" -not -name "__init__.py" -delete find . -path "*/migrations/*.pyc" -delete python3 manage.py makemigrations python3 manage.py migrate python3 manage.py createsuperuser
结果验证
迁移完成后,执行desc vcm_teacher;查看Teacher模型对应表结构,会自动继承AbstractUser的所有内置用户字段,和原生auth_user表能力完全一致,同时支持你自定义的多对多关联关系,直接将模型注册到Django Admin即可正常使用:
+--------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------------+--------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | password | varchar(128) | NO | | NULL | | | last_login | datetime(6) | YES | | NULL | | | is_superuser | tinyint(1) | NO | | NULL | | | username | varchar(150) | NO | UNI | NULL | | | first_name | varchar(150) | NO | | NULL | | | last_name | varchar(150) | NO | | NULL | | | email | varchar(254) | NO | | NULL | | | is_staff | tinyint(1) | NO | | NULL | | | is_active | tinyint(1) | NO | | NULL | | | date_joined | datetime(6) | NO | | NULL | | +--------------+--------------+------+-----+---------+----------------+
内容的提问来源于stack exchange,提问作者Harley
相关产品推荐
相关产品推荐

