django_models_外键应用_2021-11-12

一、什么是主键,什么是外键
这是一个太老声长谈的问题,我认为
1、主键:在一个数据库表格中的唯一标识,因此主键有个重要的属性,是不能重复且唯一,且不能为空,比如说,一个班级里有两个学生叫张三,学生名子显然不能作为学生表格的主键,因为我一搜张三,就会有两个张三同时跳出来,那什么可以呢,就是学号,因为学号在班级里是唯一的。其他还有很多例子,比如说,身份证号,工号等等,

2、外键:A表中的一个字段,是B表的主键,那他就可以是A表的外键,同上,如果有一个学生成绩表,学号是学生成绩表中的一个字段,那学号就是学生成绩表的外键

4、外键的存在有什么意义呢
再拿学生表和学生成绩表举例,如果我有一个学号是0003的学生,同时在成绩表中有他的一条记录,如果0003的学生转学了,我要从我的学生表里删掉他,如果没有外键,0003的成绩表中还会有他的记录,但此时,他的成绩记录已经没有意义了(人都不在了还要啥成绩),就会产生垃圾数据,所以此时外键这个概念诞生了,在删除0003这个学生的时候 ,数据库同时也会删除和0003有关系的所有成绩记录,这样数据库表之间就完整了

5、下面这个表格我觉得说的很清楚:
image.png

二、django外键应用(只是举个例子):
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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • SQL的主键和外键的作用: 外键取值规则:空值或参照的主键值。 (1)插入非空值时,如果主键表中没有这个值,则不能...
    itrojan阅读 5,099评论 0 52
  • SQL的主键和外键的作用: 外键取值规则:空值或参照的主键值。 (1)插入非空值时,如果主键表中没有这个值,则不能...
    五秋木阅读 5,553评论 0 5
  • 索引 打开 student 设计表 在大型的数据库中 添加索引能有效缩短运行时间 外键成绩表中的学号不是成绩表的主...
    Clemente阅读 3,097评论 0 0
  • 如果公共关键字在一个关系中是主关键字,那么这个公共关键字被称为另一个关系的外键。由此可见,外键表示了两个关系之间的...
    世民Young阅读 4,140评论 0 0
  • 表的约束 主键约束Primary key用于约束表中的一行,作为这一行的标识符,在一张表中通过主键就能准确定位到一...
    lufaqiang阅读 3,414评论 0 1