django_models_外键应用

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


这是一个太老声长谈的问题,我认为
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

  • 1
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在 Django 的 admin.py 中,如果要在 list_display 中显示一个的相关字段,可以使用双下划线语法。例如,如果有一个名为 Book 的模型,并且它有一个字段 author,你可以这样在 BookAdmin 中的 list_display 中显示作者的名字: ```python from django.contrib import admin from .models import Book class BookAdmin(admin.ModelAdmin): list_display = ('title', 'author__name') admin.site.register(Book, BookAdmin) ``` 其中,'author__name' 表示要显示作者的名字,其中的双下划线 '__' 表示要通过访问作者模型的 name 字段。需要注意的是,如果是多对多关系,则需要使用 'related_name' 来设置反向关联的名称,例如: ```python from django.db import models class Author(models.Model): name = models.CharField(max_length=50) class Book(models.Model): title = models.CharField(max_length=100) authors = models.ManyToManyField(Author, related_name='books') ``` 在 BookAdmin 中,可以这样显示作者们的名字: ```python class BookAdmin(admin.ModelAdmin): def authors_name(self, obj): return ', '.join([a.name for a in obj.authors.all()]) authors_name.short_description = 'Authors' list_display = ('title', 'authors_name') ``` 其中,'authors_name' 是一个自定义的方法,用来返回作者们的名字,然后在 list_display 中显示。需要注意的是,自定义的方法需要设置一个短描述 'short_description',用来在列表头部显示。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值