day4_关联关系

模型2

一、关联关系
1、概述

关联关系指的是数据表之间的数据是相互依赖和影响关系,。表之间有从属关系,对数mysql中的表之间的关系。

2、种类
  • 一对一
  • 一对多
  • 多对多
3、Model中的关联关系
OneToOneField(to=关联的类名,on_delete=级联选项)	 一对一
ForeignKey(to=关联的类名,on_delete=级联选项)		一对多
ManyToManyField(to=关联的类名)				   多对多
4、例子

一对一

class Person(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    class Meta:
        db_table="t_person"
class Passport(models.Model):
    note = models.CharField(max_length=20)
    per = models.OneToOneField(to="Person",on_delete=models.CASCADE,null=True) #关系属性
    class Meta:
        db_table="t_passport"

一对多

class Category(models.Model):
    title = models.CharField(max_length=20)
    note = models.CharField(max_length=20)
    class Meta:
        db_table="t_category"

class Goods(models.Model):
    title = models.CharField(max_length=20,unique=True)
    price = models.FloatField()
    cate = models.ForeignKey(to=Category,on_delete=models.CASCADE) #关系属性
    class Meta:
        db_table = "t_goods"

多对多

class Student(models.Model):
    name = models.CharField(max_length=20)
    age = models.IntegerField()
    class Meta:
        db_table="t_student"
        
class Course(models.Model):
    title = models.CharField(max_length=30)
    expire = models.SmallIntegerField()
    stu = models.ManyToManyField(to=Student) #关系属性
    class Meta:
        db_table="t_course"
5、关联关系查询
一对一查询
Person.objects.filter(passport__id=1)#护照的id是1的Person
查主表信息时,直接从表(双下划线)	passport__id
Passport.objects.filter(per_id=1)	#id为1的person的Passport
查从表信息时,直接用关联对象	per_id=1
保留双方的数据
Person.objects.filter(passport__country='USA').values('id','name','age','passport__country')
一对多查询
查主表
Category.objects.filter(goods__pk__gt=1)#id大于1的商品的类别
查从表
Goods.objects.filter(cate__pk__gte=1) # 类别id大于1的商品
保留双方的数据
Goods.objects.filter(cate__title__contains="s").values("cate__title","pk","price")

cs = Category.objects.all()
gs = Goods.objects.all()

cs[0].goods_set # 没有多方的关系属性,通过"多方类名_set"获得多方
                # 此时只是返回一个RelatedManger,不支持遍历和限制获取子集 而且并没有数据,可以调用QuerySet的方法
                注意(__set)只是model对象的方法
cs[0].goods_set.filter(price_gt=200)
多对多查询
和一对多一样,先查询一个
stus = Student.objects.all()
stus[0].course_set.filter(title__contains='s') #获得第一个学生的 标题中含有"s"的课程

Student.objects.filter(course__title__contains="h") #标题中含有"h"的课程中的学生
Course.objects.filter(stu__name="zzz") #姓名为zzz的学生参加的课程
6、增加数据
  • 为已存在的主表添加从表的数据
# 方式一: 先取某一个类别,再通过该类别创建一个商品
c = Category.objects.get(pk=1)   # 获取类别一对象
c.goods_set.create(title = 'abc',price=139.99)   # 不需要再save

# 方式二:先取某个类别,单独创建商品并关联类别
c = Category.objects.get(pk=1)
g = Goods.objects.create(title='abc',price=213,cate=c) #为商品的关系属性赋值
# 注意:如果是1:1,则只能使用方式二
  • 为不存在的主表添加
c = Category(title="类别1",note="xx")
g = Goods(title="zzz6",price=100)
g.save() #此时,外键的值为null
c.save()
c.goods_set.add(g) #会同步数据库,补充外键值

或

c = Category(title="类别1",note="xx")
c.save()
g = Goods(title="zzz6",price=100,cate9=c)
g.save() #此时,good是有外键值的
#注意如果是1:1只能用第二种
7、删除数据
Goods.objects.get(pk=1).delete()

注意级联选项

参数作用
CASCADE主表删,从表删
SET_NULL主表删,从表为空
PROTECT不允许直接删除主表
SET_DEFAULT删除主表,为从表设置默认值,需要加default
SET同上,不需要default,set()
DO_NOTHING删除主表,从表什么也不做
8、修改数据
查找对象,直接对象.属性改,注意得保存
cs = Category.objects.all()
c = cs[0]
c.title="new_title"
c.save()

懒加载Lazy-load

QuerySet在查询数据时,是延迟执行,直到真正使用了数据,才发起查询

  • 测试方式

找到mysql的安装目录下的my.ini文件,添加配置:

# SERVER SECTION
[mysqld]
.....
log = "E:/mysql_log.log" #设置日志文件,记录sql语句执行
或
general-log=1
general_log_file=E:/mysql_log.log		安装目录

#需要重启Mysql服务   net stop/start mysql   
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值