14、 Django-多表操作-多个模块的关联-一对多的增删改查- models.ForeignKey()

#多模块关联
    -- 关联分类:Django中的三个函数
        -- ForeignKey-称为外键:一对多、将字段定义在多的一端中
        -- ManyToMnayField:多对多、将字段定义在两端的任意一端中
        -- OneToOneField:一对一、将字段定义在任意一端中

 

如:一对一:

一对多:

多对多:常用

 

如:

模型models.py

from django.db import models


#1对多 1:N
#用户类型 :用户  -- 1:N
#一种用户类型:可以有多个用户
#一个用户:只属于一个用户类型


#用户类型
class UserTyep(models.Model):
    name = models.CharField(max_length=30)



#用户
class User(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField(default=10)

    #用户类型的对象user_type
    #使用外键ForeignKey关联两个表
    #定义外键 :外键写在多的一端 、这里关联用户类型
    #语法:关联的表名(模型类名) = models.ForeignKey(绑定的外键模型类, on_delete=models.CASCADE)
    #on_delete=models.CASCADE 级联删除:表示当用户类型中的某个字段删除后、是否也要将绑定在用户类型下的用户删除
    # user_type = models.ForeignKey(UserTyep, on_delete=models.CASCADE)   #级联模式
    #user_type = models.ForeignKey(UserTyep, on_delete=models.PROTECT)  # 保护模式
    # user_type = models.ForeignKey(UserTyep, on_delete=models.SET_NULL, null=True)  # 置空模式
    # user_type = models.ForeignKey(UserTyep, on_delete=models.SET_DEFAULT, default=0)  # 设置默认值
    # user_type = models.ForeignKey(UserTyep, on_delete=models.DO_NOTHING)  # 保护模式


    #设置related_name、设置了这个就不能使用自带的user_set属性了、直接使用 related_name='users' 中的users对象就行了
    user_type = models.ForeignKey(UserTyep, on_delete=models.PROTECT,
                                  related_name='users'
                                  )

#no_delete有以下的选项:
#   1、models.CASCADE    表示级联删除、即当删除UserType表的主键数据时、相关联的表User中的对应的外键的数据也会被删除
#   2、models.PROTECT    表示保护模式、阻止级联删除
#   3、models.SET_NULL   置空模式、设为null、相应的null=True(必须)、意思是当删除UserType表的主键数据时、相关联的表User中的对应的外键的数据不会被删除、外键变为null
#   4、models.SET_DEFAULT    #设置默认值、表示删除关联的外键值后相应的数据不会删除、但是要指定默认的外键值
#   5、models.SET()      删除的时候重新动态指向一个实体访问对应元素、可传函数、不常用、类似SET_DEFAULT
#   6、models.DO_NOTHING 什么也不做、外键不会消失也不会改变   不建议使用





#数据迁移
    #python .\manage.py makemigrations
    #python .\manage.py migrate
    #数据迁移后会在定义外键的表(字段多)自动新增一个字段:字段命名为:被绑定的外键类名小写(user_type)_主键名(id)

 

#增加数据

views.py

from django.shortcuts import render,HttpResponse
from app_mysql.models import *



#一对多的增删改查

#增
def add_user(request):
    # #给UserTyPe表添加数据
    # user_types = ['温工', '黄工', '番薯', '柱子']
    # for name in user_types:
    #     UserTyep.objects.create(name=name)


    #给User表添加数据
    for i in range(11, 30):
        # #使用用户类型的id(user_type_id-主键)绑定用户
        # User.objects.create(name=f'张三-{i}', age=i, user_type_id=i%4 + 1)

        #使用用户类型的对象绑定用户
        #user_type=UserTyep.objects.get(pk=i%4 + 1) 获取的是用户类型的id:pk为主键也是id
        User.objects.create(name=f'李四-{i}', age=100+i,
                            user_type=UserTyep.objects.get(pk=i%4 + 1)
                            )
    return HttpResponse('添加成功')


#删除数据
def del_user(request):
    # #删除User数据、对用户类型无影响
    # User.objects.filter(id=6).delete()

    #删除UserType中的数据、会影响User表中的数据
    #这里删除用户类型表中id=2的类型、会导致用户表中(外键)user_type_id=2的用户也会被删除、这就是级联删除on_delete=models.CASCADE
    UserTyep.objects.filter(id=2).delete()

    return HttpResponse('删除成功')


#修改数据
def update_user(request):
    #修改UserType表数据
    UserTyep.objects.filter(id=3).update(name='小新')

    #修改User表数据
    User.objects.filter(id=11).update(age=20)

    return HttpResponse('修改成功')

#查询数据
def get_user(request):
    # #正向查询:从User表去查找UserType表数据
    # user = User.objects.get(id=2)
    # #user.user_type 拿到的是用户类型的对象
    # print(user.name, user.age, user.user_type, user.user_type_id)
    # print(user.user_type.name, user.user_type.id)


    #反向查询:从UserType表去查对应的用户
    # utype = UserTyep.objects.get(pk=1)
    # print(utype.id, utype.name) #UserType自身的属性
    # # user_set:内部自动会生成的属性、可以让你反向查询到所关联的所有的User用户表的集合
    # #print(utype.user_set)
    # print(utype.user_set.all())     #返回查询集列表

    #使用filter查找
    #通过UserType中指定的字段查找User表中相关联的用户
    #如查找用户类型表中id=3 name='番薯' 所关联的用户
    # users = User.objects.filter(user_type=UserTyep.objects.get(name='番薯'))  #传入UserType的对象
    # users = User.objects.filter(user_type_id=3) #通过字段查找
    # users = User.objects.filter(user_type__name='番薯')   #传入UserType表中的字段


    #还可以使用 related_name查找、当使用了related_name就不能使用自带的_set相关的属性了、如utype.user_set.all()
    #需要在models中设置
    utype = UserTyep.objects.get(pk=1)
    print(utype.users.all())
    print(utype.users.filter())

    return HttpResponse('查询成功')

 

urls.py


from django.contrib import admin
from django.urls import path

from app_mysql import views as one2many_view

urlpatterns = [

    #一对多
    #增加数据路由
    path('one2many/adduser/', one2many_view.add_user),
    #删除数据路由
    path('one2many/deluser/', one2many_view.del_user),
    #修改数据
    path('one2many/updateuser/', one2many_view.update_user),
    #查询数据
    path('one2many/getuser/', one2many_view.get_user),


    path('admin/', admin.site.urls),
]

 

posted @ 2024-07-09 22:30  little小新  阅读(18)  评论(0编辑  收藏  举报