关于Django框架的关系模型序列化和一对多关系中的序列化解析
作者:想成为数据分析师的开发工程师 发布时间:2023-01-15 00:52:53
标签:Django,关系模型,序列化
1.关系模型序列化
1.1 什么是序列化?什么是反序列化?
序列化的意思是把字典的形式转化成Json格式。当我们展示数据的时候需要使用。反序列化的话,就是Json转成字典形式,存储数据时候使用。
1.2 如何实现序列化与反序列化?
实现的方法就是,通过创建一个序列化类,继承serializers.ModelSerializer。在其中改写Meta类。具体效果看代码
1.3 代码展示
一对多模型
from django.db import models
# Create your models here.
class Classes(models.Model):
name = models.CharField(max_length=20, verbose_name='班级名称')
class Student(models.Model):
SEX_CHOICES = ((1,'男'),(2,'女'))
name = models.CharField(max_length=20,verbose_name='姓名')
age = models.IntegerField(null=True, blank=True, verbose_name='年龄')
sex = models.IntegerField(choices=SEX_CHOICES,default=1,verbose_name='性别')
# 多方建立外键
classes = models.ForeignKey(Classes, on_delete=models.SET_NULL, null=True, verbose_name='班级')
序列化类
from rest_framework import serializers
from rest_app.models import *
class ClassesSerializer(serializers.ModelSerializer):
class Meta:
model = Classes
fields = ['id', 'name']
class StudentSerializer(serializers.ModelSerializer):
# 新增班级属性
classes = ClassesSerializer() # 一定要加括号,创建实例对象。否则,只能输出id
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex','classes'] #或者 ='__all__'
创建好就是迁移模型啦,Django迁移模型方法可以参考本专栏之前的文章
2. 一对多关系的增删改查
2.1 代码展示
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from rest_app.models import *
from rest_app.app_serializer import StudentSerializer,ClassesSerializer
from django.http import JsonResponse,HttpResponse
from rest_framework.parsers import JSONParser
###################一对多关系表的增删改查####################
# 完成新增 查询所有,路由相同,但是请求方式不同
@csrf_exempt # 关闭csrf中间件(防止利用cookie和token攻击网站)的使用
def classes(request):
# 判断请求方式,完成新增和查询所有
if request.method == 'GET':
# 查询所有数据
stu_list = Classes.objects.all()
# 序列化
serializer = ClassesSerializer(stu_list, many=True)
# 将json格式返回客户端
return JsonResponse(serializer.data, safe=False)
elif request.method == 'POST':
# 新增数据
# 使用JSONParaser调用parse()进行反序列化为字典
data_dict = JSONParser().parse(request)
# 将字典传入到序列化类中
serializer = ClassesSerializer(data=data_dict)
# 进行验证
if serializer.is_valid():
# 保存数据到数据库中
serializer.save()
# 返回新保存的数据 状态码 201
return JsonResponse(serializer.data, status = 201)
return JsonResponse(serializer.errors, status=400)
# 查询一个 删除 修改
@csrf_exempt # 关闭csrf中间件(防止利用cookie和token攻击网站)的使用
def classes_detail(request,pk):
try:
# 根据pk获取Classes
classes = Classes.objects.get(pk=pk)
except Classes.DoesNotExist: #无法获取到
return HttpResponse(status=404)
if request.method == 'GET':
# 根据id查询指定的Student
# 序列化——展示数据
serializer = ClassesSerializer(classes)
# 返回json数据
return JsonResponse(serializer.data)
elif request.method == 'PUT':
# 根据id修改Student
# 反序列化——获取需要使用的数据时使用
data_dict = JSONParser().parse(request)
# 将原来的对象 字典数据传入序列化类中
serializer = ClassesSerializer(classes, data=data_dict)
# 进行验证
if serializer.is_valid():
# 更新数据到数据库
serializer.save()
return JsonResponse(serializer.data)
return JsonResponse(serializer.errors, status=400)
elif request.method == 'DELETE':
# 根据id删除classes
classes.delete()
return HttpResponse(status=200)
2.2 效果展示
查询单条数据
查询全部数据
POST请求插入信息
PUT请求修改数据
DELETE删除数据
3.一对多关系中在一方想获取多方数据并序列化方法
首先,在模型中的多方应该在外键中加入属性related_name,在模型的一方中,使用属性名记录多方的序列化后字段。在fields中添加入属性名。 模型
from django.db import models
# Create your models here.
class Classes(models.Model):
name = models.CharField(max_length=20, verbose_name='班级名称')
class Student(models.Model):
SEX_CHOICES = ((1,'男'),(2,'女'))
name = models.CharField(max_length=20,verbose_name='姓名')
age = models.IntegerField(null=True, blank=True, verbose_name='年龄')
sex = models.IntegerField(choices=SEX_CHOICES,default=1,verbose_name='性别')
# 多方建立外键
classes = models.ForeignKey(Classes, related_name='students' ,on_delete=models.SET_NULL, null=True, verbose_name='班级')
序列化
from rest_framework import serializers
from rest_app.models import *
# 根据学生获取学生所在班级
# class ClassesSerializer(serializers.ModelSerializer):
# class Meta:
# model = Classes
# fields = ['id', 'name']
# class StudentSerializer(serializers.ModelSerializer):
# # 新增班级属性
# classes = ClassesSerializer() # 一定要加括号,创建实例对象。否则,只能输出id
# class Meta:
# model = Student
# fields = ['id', 'name', 'age', 'sex','classes'] #或者 ='__all__'
# 根据班级获取班级所有学生信息
class StudentSerializer(serializers.ModelSerializer):
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex'] #或者 ='__all__'
class ClassesSerializer(serializers.ModelSerializer):
# students 属性要和student类中外键classes属性 related_name='students'
# 多条记录 指定many = True, read_only=True
students = StudentSerializer(many=True, read_only=True)
class Meta:
model = Classes
fields = ['id', 'name','students']
效果展示
4. 手动处理关系字段
在上述中,由于类的引用关系的原因,左右只能自动序列化一个关系字段,如果业务需求,需要2个关系字段都序列化,那么就需要使用到serializers.RelatedField类,手动处理字段关系。
序列化
from rest_framework import serializers
from rest_app.models import *
# 根据学生获取学生所在班级
# class ClassesSerializer(serializers.ModelSerializer):
# class Meta:
# model = Classes
# fields = ['id', 'name']
# class StudentSerializer(serializers.ModelSerializer):
# # 新增班级属性
# classes = ClassesSerializer() # 一定要加括号,创建实例对象。否则,只能输出id
# class Meta:
# model = Student
# fields = ['id', 'name', 'age', 'sex','classes'] #或者 ='__all__'
class ClassesRelatedField(serializers.RelatedField):
def to_representation(self, value):
return {'id':value.id, 'name':value.name}
# 根据班级获取班级所有学生信息
class StudentSerializer(serializers.ModelSerializer):
# classes 属性名和Student类中外键属性名相同
classes = ClassesRelatedField(read_only=True)
class Meta:
model = Student
fields = ['id', 'name', 'age', 'sex','classes'] #或者 ='__all__'
class ClassesSerializer(serializers.ModelSerializer):
# students 属性要和student类中外键classes属性 related_name='students'
# 多条记录 指定many = True, read_only=True
students = StudentSerializer(many=True, read_only=True)
class Meta:
model = Classes
fields = ['id', 'name','students']
来源:https://blog.csdn.net/m0_63953077/article/details/128151130


猜你喜欢
- 项目场景:常见的表单填写中都会遇到,比如新增信息,修改信息等,如下图相信大家对上面的验证都非常熟悉了,不多哔哔 本篇文章主要 想写 验证规则
- 1.模型类中设置:null=True,表示数据库创建时该字段可不填,用NULL填充.MySQL:Null这一列,如果值为YES表示:创建一条
- 最近经常需要出一些临时性的报表,于是就用python 的smtplib 和email 两模块写了个小程序,当数据处理完后通过邮箱把报表文件从
- 方法一:直接右键,将文章路径复制下来点击Copy full Xpath使用selenium+lxml中的etree进行配合使用,使用etre
- 本文实例为大家分享了python合并同类型excel表格的具体代码,供大家参考,具体内容如下python脚本如下,验证有效。#!/usr/b
- logconfig.json{ "version":1, "disable_existing_loggers&
- 尽管很多 NoSQL 数据库近几年大放异彩,但是像 MySQL 这样的关系型数据库依然是互联网的主流数据库之一,每个学 Python 的都有
- PyQt5 QtChart-散点图QScatterSeries类将数据以散点图显示import sysimport randomfrom P
- 本文实例讲述了PHP缓存集成库phpFastCache用法。分享给大家供大家参考。具体分析如下:phpFastCache是一个开源的PHP缓
- videojs虽然已经为我们提供了较为完善的功能.但是在实际应用中,我们仍然可能需要为这个播放器添加部分功能.下面将以添加标题栏为示例简要介
- 然而,微软sql server在处理这类索引时,有个重要的缺陷,那就是把本该编译成索引seek的操作编成了索引扫描,这可能导致严重性能下降
- 一般做法都是用aspjpeg的组件,这里有份用法说明,看一下吧。aspjpeg是一款非常强大的图片处理组件,纯英文版本。不过早已经有免费版和
- 抢票脚本,python +splinter自动刷新抢票,可以成功抢到(依赖自己的网络环境太厉害,还有机器的好坏),但是感觉不是很完美。有大神
- 举例: 如:在字段名处输入:username,password,email,telphone 注意:不同的字段名用英文逗号隔开,且不支持星号
- 1 。打开您的Microsoft Visual Basic:点击确定,以下就按照蓝色的数字步骤.2 。修改工程名和类模块的名称:
- 测试sql: 代码如下:SET STATISTICS IO ON SET STATISTICS TIME ON SELECT COUNT(1
- 最近用python写了一个远程监控的程序,主要功能有:1.用邮件控制所以功能2.可以对屏幕截图,屏幕截图发送到邮箱3.可以用摄像头获取图片,
- 由于Pytorch不像TensorFlow有谷歌巨头做维护,很多功能并没有很高级的封装,比如说没有tf.one_hot函数。本篇介绍将一个m
- WAP站点,这似乎是一个有点落伍的东西。在诞生之初,它很简陋,只能通过一个叫WML的标记语言来搭建没有任何美感的文字+链接页面。而今,绝大部
- 今天来给大家推荐一个Python当中超级好用的内置函数,那便是lambda方法,本篇教程大致和大家分享什么是lambda函数lambda函数