前言
- 这是博主第一次接触学习restframework框架,很多知识点零散不系统,在这不建议将此文作为指导方向。
- 在此文讲解前,不会说明安装和配置信息,大家可以百度如何安装restframework,并自行安装成功就行。
- 在此会讲解几种序列化和反序列化的方法,表的设计是一对多结构。
代码实现
序列化
首先我们在models下新建两个模型类
class User(SoftDeleteMode):
GENDER_CHOICES = (
('1', '普通会员'),
('2', 'VIP会员')
)
name = models.CharField(max_length=100, verbose_name='昵称')
phone = models.CharField(max_length=11, verbose_name='手机号', unique=True)
password = models.CharField(max_length=255, verbose_name='密码')
level = models.CharField(max_length=20, choices=GENDER_CHOICES, verbose_name='用户身份')
class Meta:
db_table = 'user'
verbose_name = '用户表'
app_label = 'polls' # 标记是属于哪个app的models,该属性常用于models的分层
ordering = ['-id'] # 根据id倒序排列
# 调用时返回自身的属性,不然都是显示xx object
def __str__(self):
return self.name
class BookInfo(SoftDeleteMode):
title = models.CharField(max_length=20, verbose_name='名称')
read = models.IntegerField(default=0, verbose_name='阅读量')
comment = models.IntegerField(default=0, verbose_name='评论量')
author = models.ForeignKey(User, on_delete=models.CASCADE, error_messages={"does_not_exist": "作者不存在"}) # 外键
class Meta:
db_table = 'tb_books' # 指明数据库表名
verbose_name = '图书' # 在admin站点中显示的名字
app_label = 'polls' # app_lable的值为APP的名称,这样就可以将models定义到多个文件中了。
def __str__(self):
"""定义每个数据对象的显示信息"""
return self.title
每个模型定义一个serializers.ModelSerializer
class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = ['id', 'name', 'phone', 'level']
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
fields = ['id', 'title', 'read', 'comment','author']
通过postman请求我们的接口可以看到,author作为外键序列化后,返回的是User里的id。(忽略字段_create_time和_update_time)
如果我们想要返回具体外键里的值,应该怎么看呢。
- 第一种方法: 在Meta中定义一个深度
depth=1
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = BookInfo
# 取出所有的字段
fields = ['id', 'title', 'read', 'comment','author']
depth = 1
- 实现效果,可以看到会把外键相关的表数据序列化出来,而且是不可控的把表数据字段读了出来。但我们可能并不需要那么多的数据,包括用户密码等字段。
- 第二种方法: 我们定义一个
get_author()
方法
class BookSerializer(serializers.ModelSerializer):
author = serializers.SerializerMethodField()
class Meta:
.....
# 在BookSerializer中我们定义一个方法,获取外键对应的数据
def get_author(self, obj):
authors_query_set = obj.author # 拿到所有作者信息 (obj是User对象)
return [{"id": authors_query_set.id, "name": authors_query_set.name}]
- 实现效果: 可以看到,按照我们定义的方法返回了值,需要什么数据可以在get_author中添加即可,想要反序列化
{"author": 1}
作为外键添加时,不得有depth=1
。
反序列化
可以在serializers.ModelSerializer
中定义与author字段相同的属性,并实例化serializers.PrimaryKeyRelatedField
对象
class BookSerializer(serializers.ModelSerializer):
# 必须要传的参数,queryset查询集,这里我们的主表是User表,所以定义了User的查询集
# error_messages: 错误提示信息,如果对象未找到对应的key:does_not_exist
author = serializers.PrimaryKeyRelatedField(queryset=User.objects.all(), error_messages={"does_not_exist": "作者不存在"})
class Meta:
model = BookInfo
fields = ['id', 'title', 'read', 'comment']
def get_author(self, obj):
authors_query_set = obj.author # 拿到所有作者信息
return [{"id": authors_query_set.id, "name": authors_query_set.name}]
实现效果:
-
添加成功
-
添加失败