Django orm 一对多,多对多 DRF 正/反序列化器。简单使用

Django 框架操作数据库 用到的是 ORM 思想,什么是 ORM 呢?
Object Relational Mapping 对象关系映射,说白了 就是 操作数据库的 语句 和 Python 乃至 Django 的不太一样 为了 方便,面向数据库的关系更改成了 面向对象。详细点的就是,创建 实例 代替 数据库中的表,类属性就是 对应的 字段了。
接下来 执行一些简单的操作。

# models.py

# 教师表
class Teacher(models.Model):
	name = models.CharField(max_length=32)

# 学生表
class Student(models.Model):
	name = models.CharField(max_length=32)
	teacher = models.ForeignKey('Teacher', on_delete=models.CASCADE)

# 课程表	
class Course(models.Model):
	name = models.CharField(max_length=32)
    student = models.ManyToManyField('Student')

定义 视图函数:
先添加 教师的 数据

# 批量添加
Teacher.objects.bulk_create(
	name=‘老师1’, 
	name=‘老师2’, 
	name=‘老师3)

添加老师对应的 学生的信息

Student.objects.bulk_create(
	(name='学生1',teacher=1),
	(name='学生2',teacher=2),
	(name='学生3',teacher=3)
	)

查询 老师 下面的学生:

teacher = Teacher.objects.filter(id=1).first()

i for i in teacher.student_set.all()
# 也可以用 relate_name
i for i in teacher.teacher_student.all()

查询 学生 上面的老师:

student = Stuednt.objects.filter(id=1).first()
student.teacher.id   # 获取主键表字段
# teacher 是外键字段

(多对多)课程添加学生:

course = Course.objects.filter(id=1).first()
student= Student.objects.filter(id=1).first()
course.student.add(student)
# 将课程 id 是 1 的课程和 id 为 1 的学生进行关联

(多对多)学生添加课程:

student = Student.objects.filter(id=1).first()
course = Course.objects.filter(id=1).first()
student.course_set.add(course)

(多对多)查询学生对应的所有课程:

student = Student.objects.filter(id=1).first()
student.course_set.all()

(多对多)课程对应的所有学生:

course = Course.objects.filter(id=1).first()
course.student.all()

通过课程删除学生的


    # 获取课程
    course = Course.objects.filter(id=3).first()
    # 获取学生
    student = Student.objects.filter(id=2).first()

    course.stu.remove(student)

通过学生删除课程的关系

    # 获取课程
    course = Course.objects.filter(id=6).first()
    # 获取学生
    student = Student.objects.filter(id=4).first()

    student.course_set.remove(course)

序列化器

序列化器的 Serializers 和 ModelSerializer 不是定死的 谁正谁反都可以。

from rest_framework import serializers
from rest_framework.response import Response 
from . import models

序列化器 是 rest_framework 里面的一个方法 库 随你怎么定义 先学会怎么用

# settings.py
INSTALL_APP = [
	'rest_framework',
	]

借用之前创建 好的表。
因为之前 做好数据了 我们先用序列化吧

class TeacherSerializer(serializers.ModelSerializer):
	class Meta:
		model: models.Teacher
		fields = '__all__' # ['id', 'name', '列表'] ('id','name', '元祖') 这几种方法都可以
		# exclude 领域外

# views.py		
class Teacher_list(APIView):
	def get(request):
		teacher = models.Teacher.objects.all()
		t = TeacherSerializer(instance=teacher, many=True)
		return Respomse({
			'code': 200,
			'teacher_list': t.data
		})

这样数据就发送到前台了。
然后 是 学生的 序列化
(一对多)


class StudentSerializer(serializers.Modelserializer):
	teacher = serializers.CharField(source='teacher.name')
	# teacher = TeacherSerializer()
	class Meta:
		model = models.Student
		fields = ['name', 'id', 'teacher']

# views.py
class Student_list(APIView):
	def get(request):
		student = models.Student.objects.filter(id=1).first()
		s = StudentSerializer(instance=student)
		return Response({
			'code': 200,
			'student_list': s.data
			})
			

多对多的序列化

课程下面的学生
(在课程表下面是拥有 那个 ManyToMany 虚拟字段)

# 类似于 上一个 序列化 因为 多对多的本质就是由一对多
class CourseSerializer(serializers.Modelserializer):
	student = serializers.CharField(source='student.name')
	# student = StudentSerializer()
	class Meta:
		model = models.Student
		fields = ['name', 'id', 'student']

# views.py
class Course_list(APIView):
	def get(request):
		course = models.Course.objects.filter(id=1).first()
		c = CourseSerializer(instance=course)
		return Response({
			'code': 200,
			'student_list': c.data
			})
无虚拟字段

学生下面的课程

class CourseModelSerializer(serializers.ModelSerializer)
	class Meta:
		model = model.Course
		fields = '__all__'

# views.py		
class StudentSerializer(serializers.Serializer):
	name = serializers.CharField(max_length=32)
	teacher = serializers.CharField(source='teacher.name')
	# many = True 重点
	course_set = CourseModelSerializer(many=True)
	

直接序列化 第三张表

# 第三章表的序列化

class Course_Student_Serializer(serializers.Modelserializer):
	course_id = CourseSerializer()
	student_id = serializers.CharField(source='student.name')
	# student_id = StudentSerializer()
	class Meta:
		model = models.Course_Student
		fields = ['id', 'student_id', 'course_id']

# views.py
class Course_Student_list(APIView):
	def get(request):
		course = models.Course_Student.objects.all()
		cs = Course_Student_Serializer(instance=course, many=True)
		return Response({
			'code': 200,
			'student_list': cs.data
			})

反序列化

这里说明一下 反序列化的数据 更新 是根据 serializers 的底层 定义的,如果参数 传入的是 data 那么就创建, 如果是 instance 和 data 就更新。

class TeacherUNSerializer(serializers.Serializer):
	name = serializers.CharField()
	def create(self, data):
		return models.Teacher.objects.create(
			**data
			)

# views.py
class Teacher_list(APIView):
	def post(self, request):
		data  = request.data.copy()
		teacher = TeacherUNSerializer(data=data)
		if teacher.is_valid():
			teacher.save()
		print(teacher.errors)
		return Response({
			'code': 200
			})
		

一对多的反序列化

class StudentUNSerializer(serializers.Serializer):
	name = serializers.CharField()
	# teacher = TeacherUNSerializer()
	teacher_id = serializers.IntegerField()
	def create(self, data):
		return models.Student.objects.create(
			**data
			)
	def update(self, instance, data)
		return instance.update(**data)

# views.py
class Student_list(APIView):
	def post:
	# 此时 传过来的数据 就携带着 student 的外键
		student = request.data.copy()
		s = StudentUNSerializer(data=data)
		if s.is_valid():
			s.save()
		print(s.errors)
		return Response({
			'code': 200
			})

多对多 反序列化 这个就有点麻烦了
这里 着重的说一点,多对多就是 两个 或 多个 一对多。在 一对多的时候 我们都是要有一个数据的 就是这个主表 一 那么多就是新添加的了,那两个一对多 就是说 创建的连接的两张表就是 那个 一,第三张表就是记录连接的多。
所以说 两张连接表是要有 数据的。

# 假设一张表(学生表)有数据 然后同时添加 两张表
class Course_Student_UNSerializer(serializers.Serializer):
	name = serializers.CharField()
	# 因为传递过来的数据是字符 所以这里也用 字符类型
	student_ids = serializers.CharField(max_length=255, write_only=True)
	def create(self, data):
		student_ids = eval(data['student_ids'])
		# 先确定 有 id 的学生
		student = models.student.objects.filter(
			id__in = student_ids
			)
		del data['student_ids']    # 删除多余的字段
		# 删除了 学生 剩下的就都是课程的了
		c = models.Course.objects.create(
			**data
	 		)
	 	# 从 课程的 ManyToMany字段 添加 
	 	c.student.add(*student)
	 	# 最后返回的是 c 什么意思? 就是说 上面 两个结果 都会被 返回 入 第三张连接表
	 	return c

# views.py
class Course_Student_list(APIView):
    def post(self, request):
       # name (新添加的课程名)
       # [1,2] -> 学生的ID们
		data = request.data.copy()
        cs = Course_Student_UNSerializer(data=data)
        if cs.is_valid():
            cs.save()
        return Response({
       		 "code": 1
       		})

同时提醒自己 !!!

多对多的添加 就是一对多 只不过第三章表的数据要的是 实例

你可能感兴趣的:(#,Django,RESTful)