一、Django数据表关联关系映射
(1)一对一:OneToOneField
(2)一对多:Foreignkey
(3)多对多:ManyToManyField
二、一对多关系类型
如: (1)一个用户类型可以有多个用户,而一个用户只属于一个用户类型
(2)一个班级可以有多个学生, 而一个学生只能属于一个班级
(3)一个出版社可以出版很多不同的图书, 而一本图书只能属于一个出版社
(4)一个家庭可以有多个人, 而一个人只能属于一个家庭
Django 会自动将字段的名称添加“_id”作为列名,ForgienKey 的定义如下:
class django.db,model.ForeignKey(to,on_delete,**options)
有两个必填参数。to指定所关联的 Model,它的中取值可以是直接引用其他的 Model,也可以是 Model 所对应的字符串名称;on_delete当删除关联表的数据时,Django 将根据这个参数设定的值确定应该执行什么样的 SQL 约束。
on_delete 可以理解为 MySQL 外键的级联动作,当主表执行删除操作时对子表的影响,即子表要执行的操作,Django 提供的可选值如下所示:
- CASCADE,级联删除,它是大部分 ForeignKey 的定义时选择的约束。它的表现是删除了“主”,则“子”也会被自动删除。
- PROTECT,删除被引用对象时,将会抛出 ProtectedError 异常。当主表被一个或多个子表关联时,主表被删除则会抛出异常。
- SET_NULL,设置删除对象所关联的外键字段为 null,但前提是设置了选项 null 为True,否则会抛出异常。
- SET_DEFAULT:将外键字段设置为默认值,但前提是设置了 default 选项,且指向的对象是存在的。
- SET(value):删除被引用对象时,设置外键字段为 value。value 如果是一个可调用对象,那么就会被设置为调用后的结果。
- DO_NOTHING:不做任何处理。但是,由于数据表之间存在引用关系,删除关联数据,会造成数据库抛出异常。
2、语法格式:
#一个A类实例对象关联多个B类实例对象class A(model.Model): ....class B(model.Model): 属性 = models.ForeignKey(多对一中"一"的模型类, ...)
3、应用:(一个用户类型可以多个用户)CRUD操作
(1)models.py
from django.db import models# Create your models here.# one to many =1:N# 用户类型: 可以多个用户# 一个用户:只属于一个用户类型# 用户类型class UserType(models.Model):name=models.CharField(max_length=30) # 用户类型名称 :黑铁,青铜,白银,黄金,钻石class Meta:db_table='userType'verbose_name='用户类型'verbose_name_plural=verbose_name#用户表class User(models.Model):name = models.CharField(max_length=30)# 用户名称age = models.IntegerField(default=18)# 年龄#关联关系-FK(用户类型,级联删除) (自动生成 user_type_id)user_type=models.ForeignKey(UserType,on_delete=models.CASCADE)#级联删除# user_type=models.ForeignKey(UserType,on_delete=models.PROTECT) #保护模式# user_type=models.ForeignKey(UserType,on_delete=models.SET_NULL,null=True) #设置空模式# user_type=models.ForeignKey(UserType,on_delete=models.SET_DEFAULT,default=2) #设置默认模式# user_type=models.ForeignKey(UserType,on_delete=models.DO_NOTHING) #什么也不做(发生异常有提示)class Meta:db_table = 'user'verbose_name = '用户'verbose_name_plural = verbose_name
数据迁移 :python manage.py makemigrations
数据同步到数据库:python manage.py migrate
(2)views.py
from django.http import HttpResponsefrom django.shortcuts import render# Create your views here.# 一对多from onetomany.models import UserType, User# 用户类型添加数据def addUser(request):# 用户类型user_types = ['黑铁', '青铜', '白银', '黄金', '钻石', '大师', '王者']for type in user_types:UserType.objects.create(name=type)return HttpResponse('添加成功!!')# 用户添加数据def addUser2(request):# 用户 使用id进行添加for i in range(10, 31):User.objects.create(name=f'刘飞-{i}', age=i, user_type_id=i % 7 + 1)return HttpResponse('添加成功!!')# 用户添加数据def addUser3(request):# 用户 :通过对象进行添加for i in range(10, 31):User.objects.create(name=f'王芳-{i}', age=90 + i, user_type=UserType.objects.get(pk=i % 7 + 1))return HttpResponse('添加成功!!')# 删除数据def delUser(request):# 删除用户User ,此时UserType表无关# User.objects.filter(id=4).delete()# 删除UserType表数据,此时User表有关,删除UserType.objects.filter(id=1).delete()return HttpResponse('删除成功!!')# 修改数据def updateUser(request):# 修改用户类型表UserType.objects.filter(id=2).update(name='荣耀')return HttpResponse('修改成功!!')# 修改数据def updateUser2(request):# 修改用户表User.objects.filter(id=2).update(name='mike',age=18)return HttpResponse('修改成功!!')# 查询数据def getUser(request):#正向查询:从user表查找Usertype表user=User.objects.get(id=1)print(user.name,user.age,user.user_type,user.user_type_id)print(user.user_type.id,user.user_type.name)# 刘飞-10 10 UserType object (4) 4# 4 黄金return HttpResponse('查询成功!!')# 查询数据def getUser2(request):# 反向查询:从Usertype表查找user表usertype = UserType.objects.get(pk=5)print(usertype.id,usertype.name)#一对多,查询集合print(usertype.user_set.all())return HttpResponse('查询成功!!')
(3)urls.py
from django.contrib import adminfrom django.urls import path, include#导入视图fromonetomany importviews as onetomany_viewurlpatterns = [# path('onemany', include('onetomany.urls')), #子路由path('onemany/adduser/', onetomany_view.addUser), #添加path('onemany/adduser2/', onetomany_view.addUser2), #添加path('onemany/adduser3/', onetomany_view.addUser3), #添加path('onemany/del/', onetomany_view.delUser), #删除path('onemany/update/', onetomany_view.updateUser), #修改path('onemany/update2/', onetomany_view.updateUser2), #修改path('onemany/get/', onetomany_view.getUser), #查找path('onemany/get2/', onetomany_view.getUser2), #查找]
(4) 运行
添加修改删除的数据
正向查询
反向查询
(5)总结
一个用户类型可以有多个用户,而一个用户只属于一个用户类型
对象的使用:
正向 (在User这边, 有userType属性的这一边):
获取用户所在用户类型(对象) :user.user_type
获取用户所在用户类型的属性: user.user_type.name
反向 (在UserType这边):
获取用户类型的所有用户(获取Manager对象): usertype.user_set
获取用户类型的所有用户(获取QuerySet查询集): usertype.user_set.all()filter(),get()等操作中的使用:
正向 (在User这边, 有userType属性的这一边):
User.objects.filter(属性_name=’1′)
如: User.objects.filter(usertype_name=’1′)
反向 (在UserType这边):
usertype.objects.filter(类名小写_id=7)
如: usertype.objects.filter(user_id=7)