user表关联profile表
本节开始我们来实现收藏和取消收藏的功能。
在Django中,自带了一个auth_user表,用于存储用户信息,但是这个表的字段有限,所以,我们新建一个profile表,其与auth_user表是一对一关系,将额外的用户信息字段都添加到profile表中。
本节课主要介绍了在Django中如何创建和管理用户表和扩展的profile表之间的关联关系。通过使用一对一和多对多的关系,可以实现用户表和profile表之间的数据关联和操作。
创建profile表
首先,在Django的models.py文件中,创建一个Profile类作为profile表的模型。这个类与auth_user表是一对一的关联关系,与movie表是多对多的关联关系。表关系如下图所示。

在Profile类中,定义了一些扩展字段,例如手机号、邮箱和头像。同时,使用shortuuidfield模块生成一个随机的ID,而不使用自增的ID。在安装shortuuidfield模块后,需要导入该模块并在Profile类中使用它。
创建关联表
当user表和movie表之间是多对多的关系时,Django将自动创建一个关联表来管理这两个表之间的关联数据。这个关联表包含三个字段:id、profile id和movie id。通过这两个id字段,可以将用户和电影进行关联。
在account/models.py文件中新增Profile模型类, 代码如下:
from django.db import models
from django.contrib.auth.models import User
from movie.models import Movie
from shortuuidfield import ShortUUIDField
# Create your models here.
class Profile(models.Model):
uid = ShortUUIDField(max_length=32, primary_key=True, unique=True, verbose_name='用户唯一标识')
phone = models.CharField(max_length=11, blank=True, null=True, verbose_name='用户电话', db_index=True)
email = models.CharField(max_length=40, blank=True, null=True, verbose_name='用户邮箱', db_index=True)
avatar = models.CharField(max_length=60, blank=True, null=True, verbose_name='用户头像')
# 会员相关
is_upgrade = models.IntegerField(default=0, verbose_name='是否升级会员')
upgrade_time = models.DateTimeField(blank=True, null=True, verbose_name='升级日期')
expire_time = models.DateTimeField(blank=True, null=True, verbose_name='过期时间')
upgrade_count = models.IntegerField(default=0, verbose_name='升级次数')
# 关联用户表
user = models.OneToOneField(User, on_delete=models.CASCADE)
# 关联电影表
movies = models.ManyToManyField(Movie)
class Meta:
db_table = 'profile'
verbose_name = '用户信息'
verbose_name_plural = '用户信息'
上面的代码中,引入了第三方包shortuuid, 所以需要先来使用pip安装它。
pip install django-shortuuidfield
执行迁移操作
在创建profile表和关联表后,需要执行迁移操作以将这些模型应用到数据库中。通过运行python manage.py makemigrations和python manage.py migrate命令,将模型生成对应的数据表。
执行完毕后,数据库中会新增2张表,profile表和profile_movie关联表。

profile表字段如下:

其中,profile_movie表是中间表,字段如下:

创建用户和关联profile表
回顾一下我们前面讲解创建用户的流程,需要填写用户名、邮箱和密码, 如下图所示。

那么创建完成时,我们需要将auth_user表新增的user_id写入到profile表。所以,接下里,我们需要修改注册的逻辑代码。
通过Djoser模块提供的用户创建接口,我们可以自定义用户创建的过程。在下图的settings.py配置中,发现注册模块写到accout.serializers.CustomUserCreateSerializer下。

接下里,我们在CustomUserCreateSerializer下创建create()方法,重写父类的create方法,代码如下:
from account.models import Profile
class CustomUserCreateSerializer(UserCreateSerializer):
email = serializers.EmailField(
validators = [CustomUniqueValidator(queryset=User.objects.all())]
)
class Meta:
model = User
fields = ('id', 'username', 'email', 'password')
# 新增代码
def create(self, validated_data):
user = UserCreateSerializer.create(self, validated_data)
# 写入到profile表
profile = Profile(user=user)
profile.save()
return user
首先,我们继承Djoser的用户创建序列化类,并重写了其中的创建方法。为了能够继续使用Djoser的用户序列化类,我们调用了父类的序列化方法,并在父类方法执行后,添加了将用户信息写入到profile表的逻辑。在写入到profile表时,我们使用了我们创建的ofile模型,并传递了user对象作为关联字段。
最后,我们注册一个新用户来测试用户创建和profile表之间的关联关系。通过注册的接口,我们可以填写用户信息并创建新用户。在数据库中,我们可以查看到user表和profile表之间的关系已经建立起来了。
user表字段信息如下图所示。

profile表字段信息如下图所示。

【大熊课堂精品课程】
Python零基础入门动画课: https://www.bilibili.com/cheese/play/ss7988
Django+Vue:全栈开发: https://www.bilibili.com/cheese/play/ss8134
PyQT6开发桌面软件: https://www.bilibili.com/cheese/play/ss12314
Python办公自动化: https://www.bilibili.com/cheese/play/ss14990
Cursor AI编程+MCP:零基础实战项目课: https://www.bilibili.com/cheese/play/ss105194189
Pandas数据分析实战: https://www.bilibili.com/cheese/play/ss734522035
AI大模型+Python小白应用实战: https://www.bilibili.com/cheese/play/ss3844