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
})
多对多的添加 就是一对多 只不过第三章表的数据要的是 实例