Skip to main content

user表关联profile表

本节开始我们来实现收藏和取消收藏的功能。

在Django中,自带了一个auth_user表,用于存储用户信息,但是这个表的字段有限,所以,我们新建一个profile表,其与auth_user表是一对一关系,将额外的用户信息字段都添加到profile表中。

本节课主要介绍了在Django中如何创建和管理用户表和扩展的profile表之间的关联关系。通过使用一对一和多对多的关系,可以实现用户表和profile表之间的数据关联和操作。

创建profile表

首先,在Django的models.py文件中,创建一个Profile类作为profile表的模型。这个类与auth_user表是一对一的关联关系,与movie表是多对多的关联关系。表关系如下图所示。

图49-模型关系

在Profile类中,定义了一些扩展字段,例如手机号、邮箱和头像。同时,使用shortuuidfield模块生成一个随机的ID,而不使用自增的ID。在安装shortuuidfield模块后,需要导入该模块并在Profile类中使用它。

创建关联表

当user表和movie表之间是多对多的关系时,Django将自动创建一个关联表来管理这两个表之间的关联数据。这个关联表包含三个字段:id、profile id和movie id。通过这两个id字段,可以将用户和电影进行关联。

在account/models.py文件中新增Profile模型类, 代码如下:

dx_movie/account/models.py
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 makemigrationspython manage.py migrate命令,将模型生成对应的数据表。

执行完毕后,数据库中会新增2张表,profile表和profile_movie关联表。

图49-新增2张表

profile表字段如下:

图49-profile表字段信息

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

图49-profile_movie表字段信息

创建用户和关联profile表

回顾一下我们前面讲解创建用户的流程,需要填写用户名、邮箱和密码, 如下图所示。 图49-注册用户信息

那么创建完成时,我们需要将auth_user表新增的user_id写入到profile表。所以,接下里,我们需要修改注册的逻辑代码。

通过Djoser模块提供的用户创建接口,我们可以自定义用户创建的过程。在下图的settings.py配置中,发现注册模块写到accout.serializers.CustomUserCreateSerializer下。

图49-user_create

接下里,我们在CustomUserCreateSerializer下创建create()方法,重写父类的create方法,代码如下:

dx_movie/accout.serializers.CustomUserCreateSerializer
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表字段信息如下图所示。

图49-auth_user表数据

profile表字段信息如下图所示。 图49-profile表数据