django_models_外键应用

     阅读:38

一、什么是主键,什么是外键


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

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

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

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

image.png

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

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

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

image.png

4、删除前:学生表

image.png

image.png

删除前:分数表:

image.png

image.png

我只删除了学生表中学号id是12的学生,但我们发现,成绩表中关于学号12的成绩一列,也自动一并删除了

image.png

image.png