阅读:38
这是一个太老声长谈的问题,我认为
1、主键:在一个数据库表格中的唯一标识,因此主键有个重要的属性,是不能重复且唯一,且不能为空,比如说,一个班级里有两个学生叫张三,学生名子显然不能作为学生表格的主键,因为我一搜张三,就会有两个张三同时跳出来,那什么可以呢,就是学号,因为学号在班级里是唯一的。其他还有很多例子,比如说,身份证号,工号等等,
2、外键:A表中的一个字段,是B表的主键,那他就可以是A表的外键,同上,如果有一个学生成绩表,学号是学生成绩表中的一个字段,那学号就是学生成绩表的外键
4、外键的存在有什么意义呢
再拿学生表和学生成绩表举例,如果我有一个学号是0003的学生,同时在成绩表中有他的一条记录,如果0003的学生转学了,我要从我的学生表里删掉他,如果没有外键,0003的成绩表中还会有他的记录,但此时,他的成绩记录已经没有意义了(人都不在了还要啥成绩),就会产生垃圾数据,所以此时外键这个概念诞生了,在删除0003这个学生的时候 ,数据库同时也会删除和0003有关系的所有成绩记录,这样数据库表之间就完整了
5、下面这个表格我觉得说的很清楚:
image.png
1、首先创建model数据库模型
from django.db import models
class Student(models.Model):
student_id = models.CharField(max_length=5, unique=True, primary_key=True, null=False)#创建外键
student_sex = models.IntegerField(choices=((1, "男"), (0, "女")), null=False)
student_age = models.IntegerField( null=False)
class StudentScores(models.Model):
#设置外键,on_delete=models.CASCADE是级联删除,就是学生表里的数据删除,学生分数表里和他有关的数据同时自动删除,to_field是关联的外键字段
student = models.ForeignKey(to=Student,to_field="student_id", on_delete=models.CASCADE)
chinese = models.IntegerField(null=False)
math = models.IntegerField(null=False)
english = models.IntegerField(null=False)
2、插入(应当对传进来的数据做层层校验再插入,这里只讲个例子,只校验一个主键不能重复)
from rest_framework.decorators import api_view
from Demo.models import *
@api_view(["POST", ])
def api_add_student(request):
new_student_sex = 1
student_id = request.POST.get("student_id")
student_sex = request.POST.get("student_sex")
student_age = request.POST.get("student_age")
chinese = request.POST.get("chinese")
math = request.POST.get("math")
english = request.POST.get("english")
if len(Student.objects.filter(student_id=student_id)) == 0: # 学生号不能重复
if student_sex == "女":
new_student_sex = 0
student = Student.objects.create(
student_id=student_id,
student_sex=new_student_sex,
student_age=int(student_age))
StudentScores.objects.create(student=student,
math=new_math,
english=new_english,
chinese=new_chinese)
res = {"code": 0, "msg": "插入成功"}
else:
res = {"code": 1, "msg": "该学生号已存在"}
return JsonResponse(res)
基中以下代码,是往两个数据库里插入数据
student=Student.objects.create(student_id=student_id,student_sex=new_student_sex,student_age=new_student_age)
StudentScores.objects.create(student=student,math=new_math,english=new_english,chinese=new_chinese)
student = student是一种django中面向对向的写法,有点难理解,那如果写成这样,也是对的,相对好理解 student_id=student.student_id,
student=Student.objects.create(student_id=student.id,student_sex=new_student_sex,student_age=new_student_age)
StudentScores.objects.create(student_id=student.student_id,math=new_math,english=new_english,chinese=new_chinese)
image.png
2、查询
@api_view(["POST", ])
def api_find_student(request):
student_id = request.POST.get("student_id")
student = Student.objects.filter(student_id=student_id).first() #查询,先要看看这个记录在不在,再来查询
print(student)
if student not in [None, ""]:
# scores = student.studentscores_set.all().first() #一种方式是django对像思路的查询方式
scores = StudentScores.objects.filter(student_id=student_id).first()#一种是我们容易理解的,mysql语句类型的查询方式
if scores:
print(scores)
res = {"code": 0, "msg": "查询成功", "math": scores.math, "english": scores.english, "chinese": scores.chinese}
else:
res = {"code": 1, "msg": "该学生成绩没有录入"}
else:
res = {"code": 1, "msg": "该学生不存在"}
return JsonResponse(res)
image.png
3、删除
@api_view(["POST", ])
def api_delete_student(request):
student_id = request.POST.get("student_id")
student = Student.objects.filter(student_id=student_id).first()#先查询,如果有这条记录再删除
print(student)
if student not in [None, ""]:
student.delete()
res = {"code": 0, "msg": "%s删除成功" % student_id}
else:
res = {"code": 1, "msg": "该学生不存在"}
return JsonResponse(res)
image.png
4、删除前:学生表
image.png
删除前:分数表:
image.png
我只删除了学生表中学号id是12的学生,但我们发现,成绩表中关于学号12的成绩一列,也自动一并删除了
image.png