Django -- 多表操作

表之间的关系

  • 一对一

    xx=models.OneToOneField(to=‘要关联的表名‘,to_field=‘要关联表名的字段‘,on_delete=models.CASCADE)
    # on_delete 删除时的一些级联效果,to_field可以不用写,默认是关联到另一张表的主键,on_field在1.x版本的Django中不用写,默认是级联删除的,2.x的版本中必须要写
  • 一对多

    xx=models.foreignKey(to=‘要关联的表名‘,to_field=‘要关联表名的字段‘,on_delete=models.CASCADE)
  • 多对多

    xx = models.ManyToManyField(to=‘另外一个表名‘) #这是自动创建的第三表

    

建表准备

  • 建立四张表: 作者表 -- 作者信息表 -- 出版社表 -- 书籍表
  • 表之间的对应关系如下
    • 一个作者应该对应一个相应的作者信息,所以作者表与作者信息表的关系为一对一 :  oneToOnefield
    • 一个出版社可以出版很多书,一本书也可以有多个出版社出版,为多对多,但是在这里将此设置为一个出版社出很对书,一对多的关系: foreignkey
    • 作者和书籍的关系为多对多: ManyToManyField

    

# 作者表
class Author(models.Model):
    name=models.CharField( max_length=32)
    age=models.IntegerField()
#authorDetail=models.OneToOneField(to="AuthorDetail",to_field="nid",on_delete=models.CASCADE)
    authorDetail=models.OneToOneField(to=‘AuthorDetail‘)  #一对一到AuthorDetail表  生成为表字段之后,会自动变为authorDetail_id这样的一个名称
    def __str__(self):
        return self.name

# 作者详细信息表
class AuthorDetail(models.Model):
    birthday=models.DateField()
    telephone=models.CharField(max_length=32)
    addr=models.CharField( max_length=64)
    def __str__(self):
        return self.addr

# 出版社表和书籍表 是 一对多的关系
class Publish(models.Model):
    name=models.CharField( max_length=32)
    city=models.CharField( max_length=32)
    email=models.EmailField()
    def __str__(self):
        return self.name

# 书籍表
class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField( max_length=32)
    publishDate=models.DateField()
    price=models.DecimalField(max_digits=5,decimal_places=2)  # 整数位5位,小数位2位
    publishs=models.ForeignKey(to="Publish")
    authors=models.ManyToManyField(to=‘Author‘,) # 注意不管是一对多还是多对多,写to这个参数的时候,最后后面的值是个字符串,不然你就需要将你要关联的那个表放到这个表的上面
    def __str__(self):
        return self.title

  

增加数据

  • 一对一增加(先给作者详细信息表中增加数据,再增加作者表的数据)

    new_author_detail = models.AuthorDetail.objects.create(
        birthday=‘1979-08-08‘,
        telephone=‘138383838‘,
        addr=‘北京‘,
    )
    obj = models.AuthorDetail.objects.filter(addr=‘山西‘).first()
    
    #方式1
    models.Author.objects.create(
        name=‘张三‘,
        age=‘40‘,
        authorDetail=new_author_detail,
    )
    # 方式2  常用
    models.Author.objects.create(
        name=‘张三‘,
        age=‘40‘,
        authorDetail_id=obj.id,
    )
  • 一对多增加

    # 方式1
    models.Book.objects.create(
        title = ‘追风筝的人‘,
        publishDate=‘2019-07-22‘,
        price=25,
        publishs=models.Publish.objects.get(id=1),
    )
    
    # 方式2 常用
    obj = models.Publish.objects.get(id=1)
    models.Book.objects.create(
        title=‘追风筝的人‘,
        publishDate=‘2019-07-21‘,
        price=25,
        publishs_id=obj.id
    )
  • 多对多增加

    # 方式1   常用
    book_obj = models.Book.objects.get(id=1)  # 拿到book的id
    book_obj.authors.add(*[1,2])  # 插入作者的id 打散的形式插入
    
    # 方式2
    author1 = models.Author.objects.get(id=1)
    author2 = models.Author.objects.get(id=3)
    book_obj = models.Book.objects.get(nid=5)
    book_obj.authors.add(*[author1,author2])

删除数据

一对一和一对多的删除和单表删除是一样的
# 一对一  表一外键关联到表二,表一删除,不影响表2,表2删除会影响表1
# 作者表外键关联作者详细信息表

models.AuthorDetail.objects.get(id=2).delete() # 作者表会受影响
models.Author.objects.get(id=3).delete()    # 作者详细信息表不会影响

# 一对多
# 书籍表外键关联出版社表

models.Publish.objects.get(id=1).delete() # 书籍表会影响
models.Book.objects.get(id=1).delete()    # 出版社表不会影响

# 多对多关系删除
book_obj = models.Book.objects.get(nid=6)
book_obj.authors.remove(6)  # 删除书id为6和作者id为6的一行数据
book_obj.authors.remove(*[5,6])

book_obj.authors.clear()  # 清空表中所有数据

book_obj.authors.set(‘1‘)  #删除然后更新,后面写字符串
book_obj.authors.set([‘5‘,‘6‘])

更新数据

# 一对一
models.Author.objects.filter(id=5).update(
    name=‘张三‘,
    age=16,
    authorDetail=models.AuthorDetail.objects.get(id=5),
    authorDetail_id=4,
)

#一对多
models.Book.objects.filter(pk=4).update(     # pk=4等价于id=4
    title=‘白夜行‘,
    publishs=models.Publish.objects.get(id=3),
    publishs_id=3,
)

#一对多
models.Publish.objects.filter(pk=2).update(
    id=4, # 没有级联更新,报错!!
)

基于对象的跨表查询

  • 类似于子查询
  • 正向查询和反向查询: 关系属性(字段)写在哪个类(表)里面,从当前类(表)的数据去查询它关联类(表)的数据叫做正向查询,反之叫做反向查询

  

############## 一对一
查询Alex的电话号码(正向查询)
obj = models.Author.objects.get(name=‘alex‘)
print(obj.authorDetail.telephone)

反向查询: 查询333这个号码是谁的
#obj = models.AuthorDetail.objects.filter(telephone=‘333‘).first().author.name
obj = models.AuthorDetail.objects.get(telephone=‘333‘).author.name
print(obj)

    ‘‘‘        正向查询: Authorobj.authorDetail,对象.关联属性名称
        Author -----------------------------------> AuthorDetail
               <-----------------------------------
              反向查询: AuthorDetailobj.author  ,对象.小写类名
    ‘‘‘

######### 一对多
查询追风筝的人是哪个出版社出版的(正向查询)
obj = models.Book.objects.get(title=‘追风筝的人‘)
print(obj.publishs.name,obj.publishs.city)

查看新华出版社出了什么书(反向查询)
obj = models.Publish.objects.get(name=‘人民出版社‘)
for i in obj.book_set.all():   # 循环拿到具体的值
    print(i)

    ‘‘‘   正向查询 book_obj.publishs  对象.属性
    Book ---------------------------------------------> Publish
        <----------------------------------------------
          反向查询 publish_obj.book_set.all()  对象.表名小写_set
    ‘‘‘

########## 多对多
查看狼道这本书是谁写的(正向查询)
obj = models.Book.objects.get(title=‘狼道‘)
for i in obj.authors.all():
    print(i)

查询张三写过什么书(反向查询)
obj = models.Author.objects.get(name=‘张三‘)
for i in obj.book_set.all():
    print(i)

    ‘‘‘       正向查询 book_obj.authors.all()  对象.属性
        Book ---------------------------------------------> Author
            <----------------------------------------------
              反向查询 author_obj.book_set.all()  对象.表名小写_set
    ‘‘‘

基于双下划线的跨表查询

  • 类似于连表查询
  • ########### 一对一
    查询lisi的电话号码(正向查询)
    obj=models.Author.objects.filter(name=‘lisi‘)
    print(obj.values(‘authorDetail__telephone‘)[0][‘authorDetail__telephone‘])
    
    obj = models.AuthorDetail.objects.filter(author__name=‘lisi‘).values(‘telephone‘)
    print(obj)
    
    查询333电话是谁的
    obj = models.AuthorDetail.objects.filter(telephone=‘333‘)
    print(obj.values(‘author__name‘))
    
    obj = models.Author.objects.filter(authorDetail__telephone=‘333‘).values(‘name‘)
    print(obj)
    
    ################# 一对多
    查询狼道是那个出版社出版的
    obj = models.Book.objects.filter(title=‘狼道‘).values(‘publishs__name‘)
    print(obj)
    
    obj = models.Publish.objects.filter(book__title=‘狼道‘).values(‘name‘)
    print(obj)
    
    查询新华出版社出版了什么书
    obj = models.Publish.objects.filter(name=‘新华出版社‘).values(‘book__title‘)
    print(obj)
    
    obj = models.Book.objects.filter(publishs__name=‘新华出版社‘).values(‘title‘)
    print(obj)
    
    ################ 多对多
    解忧杂货店这本书是谁写的
    obj = models.Book.objects.filter(title=‘解忧杂货店‘).values(‘authors__name‘)
    print(obj)
    
    obj = models.Author.objects.filter(book__title=‘解忧杂货店‘).values(‘name‘)
    print(obj)
    
    alex写了什么书
    obj= models.Author.objects.filter(name=‘alex‘).values(‘book__title‘)
    # print(obj)
    
    obj = models.Book.objects.filter(authors__name=‘alex‘).values(‘title‘)
    print(obj)
    
    ############### 进阶的
    玄机出版社 出版的书名称及作者的名称
    obj = models.Publish.objects.filter(name=‘玄机出版                                社‘).values(‘book__title‘,‘book__authors__name‘)
    print(obj)
    
    obj = models.Book.objects.filter(publishs__name=‘玄机出版社‘).values(‘title‘,‘authors__name‘)
    print(obj)
    
    obj = models.Author.objects.filter(book__publishs__name=‘玄机出版社‘).values(‘name‘,‘book__title‘)
    print(obj)

原文地址:https://www.cnblogs.com/wenxin1120/p/11260941.html

时间: 2024-10-01 21:18:48

Django -- 多表操作的相关文章

Django多表操作

多表操作:以book,publish, author为例 一对多:一旦确定一对多的关系,在多的一方(book)创建关联字段publish_id 多对多:一旦确定多对多的关系,创建第三张表,比如Author2Book表,字段分别是id,Book_id, Author_id 一对一:两张表其实就是一张表,在任意一张表创建关联字段 from django.db import models # Create your models here. #不用创建ID,Django自动创建主键 class Boo

Django -- 单表操作

ORM简介 1, ORM是 对象--关系--映射 的简称.实现了数据模型与数据库的解耦,即数据库的设计不需要依赖特定的数据库,通过简单的配置就可以轻松更换数据库 2, 类对象 --> sql --> pymysql --> mysql服务端 --> 磁盘,orm其实就是将类对象的语法翻译成sql语句的一个引擎 建表操作 1, 创建表 # app 应用下的 models.py 文件中写 from django.db import models class UserInfo(model

Django分表操作及FQ方法

聚合 aggregate(*args, **kwargs) # 计算所有图书的平均价格 from django.db.models import Avg Book.objects.all().aggregate(Avg('price')) #{'price__avg': 34.35} aggregate()是QuerySet 的一个终止子句,意思是说,它返回一个包含一些键值对的字典.键的名称是聚合值的标识符,值是计算出来的聚合值.键的名称是按照字段和聚合函数的名称自动生成出来的.如果你想要为聚合

django单表操作

python——Django(ORM连表操作)

一对多 class UserType(models.Model): caption = models.CharField(max_length=32) class UserInfo(models.Model): user_type = models.ForeignKey(UserType)# user_type对象中封装id,caption username = models.CharField(max_length=32) age = models.IntegerField() 增: 1.外键

Django开发:(3.1)ORM:单表操作

MVC或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库,通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员的工作量,不需要面对因数据库变更而导致的无效劳动 ORM是"对象-关系-映射"的简称. Mysql中的表对应python中的类,表的字段对应类的属性,表的记录对应类的实例化的对象 单表操作 创建表 1. 创建模型 创建名为app01的app,在app01下的models.py中创建模型: from dj

django的多表操作

django的多表操作 1.使用场景 在实际生产过程多,我们面对的数据纷繁复杂,此时就需要良好的数据结构设计,多表之间的约束关系为我们提供了数据管理以及查询的便利.在MYsql中我们利用外键(foreign key)来实现这样的约束关系,在django中我们通过调用相应的API来实现这样的功能. 2.创建模型 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄.作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(

django模型层2 多表操作

1.多表操作: 1.创建模型: 实例:我们来假定下面这些概念,字段和关系 作者模型:一个作者有姓名和年龄. 作者详细模型:把作者的详情放到详情表,包含生日,手机号,家庭住址等信息.作者详情模型和作者模型之间是一对一的关系(one-to-one) 出版商模型:出版商有名称,所在城市以及email. 书籍模型: 书籍有书名和出版日期,一本书可能会有多个作者,一个作者也可以写多本书,所以作者和书籍的关系就是多对多的关联关系(many-to-many);一本书只应该由一个出版商出版,所以出版商和书籍是一

Django学习手册 - ORM 数据表操作

queryset 数据类型介绍 QuerySet与惰性机制 所谓惰性机制:表名.objects.all()或者.filter()等都只是返回了一个QuerySet(查询结果集对象),它并不会马上执行sql,而是当调用QuerySet的时候才执行. QuerySet特点: <1>  可迭代的 <2>  可切片 <3>  惰性计算和缓存机制 例: info=models.table_name.objects.all()[0:5] #切片 info= models.table