Django 模型操作 - 一对多(八)

一、Django数据表关联关系映射

(1)一对一:OneToOneField

(2)一对多:Foreignkey

(3)多对多:ManyToManyField

二、一对多关系类型

  如: (1)一个用户类型可以有多个用户,而一个用户只属于一个用户类型

          (2) 一个班级可以有多个学生, 而一个学生只能属于一个班级

          (3)一个出版社可以出版很多不同的图书, 而一本图书只能属于一个出版社

          (4)一个家庭可以有多个人, 而一个人只能属于一个家庭

Django 模型操作 - 一对多(八)_第1张图片

  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 HttpResponse
from 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 admin
from django.urls import path, include
#导入视图
from  onetomany import  views as onetomany_view

urlpatterns = [
    # 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) 运行

添加修改删除的数据 

Django 模型操作 - 一对多(八)_第2张图片Django 模型操作 - 一对多(八)_第3张图片

 正向查询 

 

反向查询 

(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)

你可能感兴趣的:(django,python,后端)