首页 > 其他 > 详细

模型层之多表操作

时间:2019-07-21 23:10:48      阅读:69      评论:0      收藏:0      [点我收藏+]

一、创建模型

各模型字段

图书表book:id,title,price,publish_date

作者表author:id,name,age

出版社表publish:id,name,addr,email

作者详情表:id,phone,addr

表之间的关系

图书表和作者表是多对多关系

图书表和出版社表是多对一关系

作者表和作者详情表是一对一关系

class Book(models.Model):
    # 主键不指定默认创建id字段为主键
    title = models.CharField(max_length=32)
    price = models.DecimalField(max_digits=8,decimal_places=2)
    publish_date = models.DateField(auto_now_add=True)  # auto_now:每次操作改数据都会自动更新时间,auto_now_add:新增数据的时候会将当前时间自动添加,后续的修改该字段不会自动更新
    # 外键关系
    publish = models.ForeignKey(to=Publish)
    authors = models.ManyToManyField(to=Author)  # 虚拟字段, 信号字段

    def __str__(self):
        return 书籍对象的名字:%s%self.title


class Publish(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)
    email = models.EmailField()  # 对应就是varchar类型

    def __str__(self):
        return 出版社对象的名字:%s%self.name


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    authordetail = models.OneToOneField(to=AuthorDetail)

    def __str__(self):
        return  作者对象的名字:%s%self.name


class AuthorDetail(models.Model):
    phone = models.CharField(max_length=32)
    addr = models.CharField(max_length=32)

二、多对一(一对一)表关系记录操作

2.1 新增表记录

# 1.直接写数据:publish_id=1

models.Book.objects.create(title=红楼梦,price=66.66,publish_id=1)

# 2.传数据对象:publish=publish_obj
publish_obj = models.Publish.objects.filter(pk=2).first()  # pk指主键
models.Book.objects.create(title=三国演义,price=199.99,publish=publish_obj)

2.2 修改表数据

# 基于对象操作
book_object = models.Book.objects.get(pk = 1)
publish_object = models.Book.objects.get(pk = 2)
book.publish = publish_object  # 或者book.publish_id = 2
book.save()

# 基于Queryset操作
publish_object = models.Book.objects.filter(pk = 2).first()
book_object = models.Book.objects.filter(pk = 1).update(publish = publish_object)  # book_object = models.Book.objects.filter(pk = 1).update(publish_id = 2)

2.3 删除表记录

  同单表操作里的删除操作

三、多对多表关系记录操作

3.1 新增表记录

# 数字id,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.add(数字(id),……)

# 对象,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.add(表2_object,……)

3.2 删除表记录

# 数字id,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.remove(数字(id),……)

# 对象,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.remove(表2_object,……)

3.3 清空表记录

表1_object.与表2的关联字段.clear()  # 不需要传参数

3.4 修改表记录

  本质上就是先清空,再新增

# set:传的必须是可迭代对象(用列表或元祖形式)
# 数字id,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.set([数字(id),……])

# 对象,可传多个
表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()
表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()
表1_object.与表2的关联字段.set([表2_object,……])

四、基于对象的跨表查询(SQL的子查询)

正向:关联字段在表内

反向:关联字段不在表内

4.1 一对一

正向:按字段查询

表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()

表2_object = 表1_object.与表2的关联字段

表2_object.表2需查询字段  # 查询结果

 

反向:按表名小写查询

表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()

表1_object = 表2_object.表1名小写

表1_object.表1需查询字段  # 查询结果

4.2 多对一

正向:按字段查询

表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()

表2_object = 表1_object.与表2的关联字段

表2_object.表2需查询字段  # 查询结果

反向:按表名小写_set.all()查询

表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()

表1数据 = 表2_object.表1名小写_set.all()  # Queryset对象

  若只想要拿出查询记录的某一列,因为是一个Queryset对象,Queryset对象可以无限用句点符.查询,所以可以用.values(‘字段‘)得到。

4.3 多对多

正向:按字段.all()查询

表1_object = models.对应表1的类名.objects.filter(字段名 = 值[查找条件]).first()

表2数据 = 表1_object.与表2的关联字段.all()  # Queryset对象

反向:按表名小写_set.all()查询

表2_object = models.对应表2的类名.objects.filter(字段名 = 值[查找条件]).first()

表1数据 = 表2_object.表1名小写_set.all()  # Queryset对象

4.4 连续跨表

栗子

#查询三国演义这本书所有作者的手机号
book_obj = models.Book.objects.filter(name =三国演义).first()

authors = book_obj.authors.all() 

for author in authors:
    authordetail = author.authordetail
    print(authordetail.phone)

五、基于双下划线的跨表查询(SQL的连表查询)

1.确定以哪张表为查询基表来捋清楚正反向,正向按关联字段__查询字段,反向按表名小写__查询字段。

2.查询字段在不在基表里,不在用双下划线转到目标表。

3.跨表可以在filter,也可以在values里

栗子:查询moonzier作者的性别和手机号

# 正向(filter不用跨表)
result = Author.objects.filter(name = moonzier).values(sex,authordetail__phone)

# 反向(filter需要跨表)
result = AuthorDetail.objects.filter(author__name = moonzier).values(author__sex,phone)

 

模型层之多表操作

原文:https://www.cnblogs.com/moonzier/p/11223028.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!