如何进行ORM多表操作

技术如何进行ORM多表操作本篇文章为大家展示了如何进行ORM多表操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。1.建表from django.db import models

本篇文章为大家展示了如何进行对象关系映射(对象关系映射)多表操作,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

1.建表

来自django。dbimportmodels

#在此创建您的模型。

classAuthorDtail(模型。型号):

nid=模型。自动字段(主键=真)

生日=模特。日期字段()

电话=型号BigIntegerField()

addr=模型。字符字段(最大长度=64)

类作者(模型。型号):

nid=模型。自动字段(主键=真)

名称=型号。字符字段(最大长度=32)

年龄=模特英特尔场()

#一个字段可以建立在两个模型中的任意一个

authorDetail=模型一个toonefield(to=' Authordail ',to_field='nid ',on_delete=models .CASCADE)

类发布(模型。型号):

nid=模型。自动字段(主键=真)

名称=型号。字符字段(最大长度=32)

城市=模型。字符字段(最大长度=32)

电子邮件=模型EmailField()

classBook(模型。型号):

nid=模型。自动字段(主键=真)

标题=模型。字符字段(最大长度=32)

发布日期=模型。日期字段()

价格=型号。十进制字段(最大位数=9,小数位数=2)

#与出版建立一对多的关系,外键字段建立在多的一方

发布=模型ForeignKey(to='Publish ',to_field='nid ',on_delete=models .CASCADE)

#多对多,ManyToManyField可以建在两个模型中的任意一个,自动创建第三张表

作者=模型。曼托马尼菲尔德(致='作者)如何进行ORM多表操作

如何进行ORM多表操作

如何进行ORM多表操作

如何进行ORM多表操作

MySQL查看建表语句

CREATE TABLE `app1_authordetail` (
  `nid` int(11) NOT NULL AUTO_INCREMENT,
  `birthday` date NOT NULL,
  `telephone` bigint(20) NOT NULL,
  `addr` varchar(64) NOT NULL,
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#UNIQUE KEY `authorDetail_id` (`authorDetail_id`),这是OneToOneField创建的。
CREATE TABLE `app1_author` (
  `nid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `age` int(11) NOT NULL,
  `authorDetail_id` int(11) NOT NULL,
  PRIMARY KEY (`nid`),
  UNIQUE KEY `authorDetail_id` (`authorDetail_id`),
  CONSTRAINT `app1_author_authorDetail_id_d894fd2a_fk_app1_authordetail_nid` FOREIGN KEY (`authorDetail_id`) REFERENCES `app1_authordetail` (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app1_publish` (
  `nid` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(32) NOT NULL,
  `city` varchar(32) NOT NULL,
  `email` varchar(254) NOT NULL,
  PRIMARY KEY (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app1_book` (
  `nid` int(11) NOT NULL AUTO_INCREMENT,
  `title` varchar(32) NOT NULL,
  `publishDate` date NOT NULL,
  `price` decimal(9,2) NOT NULL,
  `publish_id` int(11) NOT NULL,
  PRIMARY KEY (`nid`),
  KEY `app1_book_publish_id_e41ee7e4` (`publish_id`),
  CONSTRAINT `app1_book_publish_id_e41ee7e4_fk_app1_publish_nid` FOREIGN KEY (`publish_id`) REFERENCES `app1_publish` (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
#ManyToManyField创建的第三方表
CREATE TABLE `app1_book_authors` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `book_id` int(11) NOT NULL,
  `author_id` int(11) NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `app1_book_authors_book_id_author_id_ce887e61_uniq` (`book_id`,`author_id`),
  KEY `app1_book_authors_author_id_89b9ee26_fk_app1_author_nid` (`author_id`),
  CONSTRAINT `app1_book_authors_author_id_89b9ee26_fk_app1_author_nid` FOREIGN KEY (`author_id`) REFERENCES `app1_author` (`nid`),
  CONSTRAINT `app1_book_authors_book_id_75b281cd_fk_app1_book_nid` FOREIGN KEY (`book_id`) REFERENCES `app1_book` (`nid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
1.表的名称是app_modelName,是根据模型中的元数据自动生成的,也可以重写为别的名称。
2.如果没有定义AutoField(),默认会创建id字段,为主键。
3.对于外键字段,Django会在字段上添加"_id"来设置列名。
4.Django会根据settings中指定的数据库类型来使用相应的SQL语句。
5.要在INSTALL_APPS中设置models.py所在的应用名称
6.外键字段 ForeignKey 有一个 null=True 的设置(它允许外键接受空值 NULL),你可以赋给它空值 None 。

2.多表ORM的增删改查

2.1插入数据

如何进行ORM多表操作

2.1.1一对多插入数据

from django.shortcuts import render
from app1.models import *
def index(request):
    # 注意:这里一定要是一个model对象,不能是queryset对象
    # 方式一:设置publish,是一个Model对象。
    publish_obj = Publish.objects.get(nid=1)
    aa_book_obj = Book.objects.create(title="AA_title",publishDate="2012-12-12",price=100,publish=publish_obj)
    # 方式二:设置publish_id
    bb_book_obj = Book.objects.create(title="BB_title", publishDate="2012-12-12", price=100, publish_id=2)
    print(aa_book_obj.title)
    print(aa_book_obj.publish.name)
    print(bb_book_obj.title)
    print(bb_book_obj.publish.name)
    # 这里关键在于publish与publish_id的区别。
    # 可以发现,
    # publish是一个对象,可以通过publish调用相应Publish表中的字段数据
    # publish_id只是Book表中的一个字段值
    print(bb_book_obj.publish.nid)
    print(bb_book_obj.publish_id)
    return render(request, "index.html")
查询title为AA_title的出版社邮箱
book_obj=Book.objects.filter(title="AA_title").first()
 print(book_obj.publish.email)

如何进行ORM多表操作

2.1.2多对多插入数据

from django.shortcuts import render
from app1.models import *
def index(request):
    # 绑定多对多关系
    cc_book_obj = Book.objects.create(title="CC_title",publishDate="2018-12-12",price=120,publish_id=1)
    vita = Author.objects.get(name="vita")
    lili = Author.objects.get(name="lili")
    # 方式一:add-author对象
    cc_book_obj.authors.add(vita,lili)
    # 方式二:add-author_id
    dd_book_obj = Book.objects.create(title="DD_title",publishDate="2018-12-12",price=120,publish_id=1)
    dd_book_obj.authors.add(1,2)
    # 方式三:add-*[1,2,3]
    ee_book_obj = Book.objects.create(title="EE_title", publishDate="2018-12-12", price=120, publish_id=1)
    ee_book_obj.authors.add(*[1,2])
    return render(request, "index.html")

如何进行ORM多表操作

2.1.3多对多的关键点

from django.shortcuts import render
from app1.models import *
def index(request):
    ee_book_obj = Book.objects.filter(title="EE_title").first()
    # 关键点:ee_book_obj.authors.all()
    # 与本书关联的所有作者信息集合,是queryset对象
    # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
    print(ee_book_obj.authors.all())
    return render(request, "index.html")

如何进行ORM多表操作

2.1.4多对多解除绑定

book_obj.authors.remove()      # 将某个特定的对象从被关联对象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear()       #清空被关联对象集合
book_obj.authors.set()         #先清空再设置
from django.shortcuts import render
from app1.models import *
def index(request):
    vita = Author.objects.filter(name="vita").first()
    aa_book_obj = Book.objects.filter(title="CC_title").first()
    # 方式一:remove-author对象
    aa_book_obj.authors.remove(vita)
    # 方式二:remove-author的nid
    aa_book_obj.authors.remove(2)
    bb_book_obj = Book.objects.filter(title="DD_title").first()
    # 方式三:remove-*[1,2]
    bb_book_obj.authors.remove(*[1,2])
    return render(request, "index.html")

如何进行ORM多表操作

2.2跨表查询

1 基于对象查询
2 基于双下划线查询
3 聚合和分组查询
4 F 与 Q查询

2.2.1正向查询与反向查询

一对多关系中,models.ForeignKey设置在book中,
根据book表查询author信息,是正向查询
根据author表查询book信息,是反向查询
多对多关系中,models.ManyToMany设置在book表中,
根据book表查询author信息,是正向查询
根据author表查询book信息,是反向查询
一对一关系中,models.OneToOne设置在author表中,
根据author表查询authoDetail信息,是正向查询
根据authorDetail表查询quthor信息,是反向查询
守则:
正想查询按字段
反向查询按表名
详解:
正向查询按字段,models.py中设置的关联字段,即Author类中的authorDetail,Book类中的publish和author。
(一对多,多对多)反向查询按表名小写_set----因为是多个数据,所以使用set,集合之意。
(一对一)反向查询按表名小写----因为只有一条对应数据,所以无set。

2.2.2基于对象查询----子查询

守则:
正想查询按字段
反向查询按表名
详解:
正向查询按字段,models.py中设置的关联字段,即Author类中的authorDetail,Book类中的publish和author。
(一对多,多对多)反向查询按表名小写_set----因为是多个数据,所以使用set,集合之意。
(一对一)反向查询按表名小写----因为只有一条对应数据,所以无set。
2.2.2.1准备数据

如何进行ORM多表操作
如何进行ORM多表操作
如何进行ORM多表操作

如何进行ORM多表操作
如何进行ORM多表操作

2.2.2.2基于对象查询--一对多查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 一对多的正向查询:查询三国演义这本书的出版社名字
    # 一本书只对应一个出版社,返回值是一个model对象
    publish_obj = Book.objects.filter(title="SanGuo").first().publish
    print(publish_obj)  # Publish object (1)
    print(publish_obj.name)  # AA出版社
    # SQL语句:
    # 一对多的反向查询:查询 AA_出版社 出版过的书籍名称
    # 一个出版社对应多本书,返回值是一个queryset集合
    book_list = Publish.objects.filter(name="AA_publish").first().book_set.all()
    print(book_list)  # <QuerySet [<Book: Book object (7)>, <Book: Book object (9)>, <Book: Book object (10)>, <Book: Book object (11)>]>
    # SQL语句:
    return render(request, "index.html")

如何进行ORM多表操作

2.2.2.3基于对象查询--多对多查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 多对多正向查询:查询Sanguo这本书的所有作者名字
    # 书和作者是多对多关系,返回值是queryset集合。
    # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>
    author_list = Book.objects.filter(title="SanGuo").first().authors.all()
    print(author_list)
    # 多对多反向查询:查询vita出版过的所有书籍名称
    # 书和作者是多对多关系,返回值是queryset集合。
    # <QuerySet [<Book: Book object (7)>, <Book: Book object (8)>, <Book: Book object (9)>, <Book: Book object (10)>, <Book: Book object (11)>]>
    book_list = Author.objects.filter(name="vita").first().book_set.all()
    print(book_list)
    return render(request, "index.html")

如何进行ORM多表操作

2.2.2.4基于对象查询--一对一查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 一对一的正向查询:查询vita的手机号
    # 一对一关系,返回值是model对象
    # AuthorDetail object (1)
    author_detail_obj = Author.objects.filter(name="vita").first().authorDetail
    print(author_detail_obj)
    # 一对一的反向查询:查询手机号为112233的作者
    # 一对一关系,返回值是model对象
    # Author object (1)
    author_obj = AuthorDetail.objects.filter(telephone="112233").first().author
    print(author_obj)
    return render(request, "index.html")

如何进行ORM多表操作

2.2.3基于双下划线的跨表查询----join查询

守则:
正想查询按字段
反向查询按表名
2.2.3.1基于双下划线的跨表查询--一对多查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 一对多查询:查询SanGuo这本书的出版社名字
    # 返回值是queryset对象
    # 方式一正向查询:
    ret = Book.objects.filter(title="SanGuo").values("publish__name")
    print(ret)  # <QuerySet [{'publish__name': 'AA_publish'}]>
    # 方式二反向查询:
    ret2 = Publish.objects.filter(book__title="SanGuo").values("name")
    print(ret2)  # <QuerySet [{'name': 'AA_publish'}]>
    # 一对多查询:查询 AA_publish出版社出版的书籍名称
    # 返回值是queryset对象
    # 方式一正向查询:
    ret3 = Publish.objects.filter(name="AA_publish").values("book__title")
    print(ret3)  # <QuerySet [{'book__title': 'SanGuo'}, {'book__title': 'HongLou'}, {'book__title': 'XiYou'}, {'book__title': 'XiaoWangZi'}]>
    # 方式二反向查询:
    ret4 = Book.objects.filter(publish__name="AA_publish").values("title")
    print(ret4)  # <QuerySet [{'title': 'SanGuo'}, {'title': 'HongLou'}, {'title': 'XiYou'}, {'title': 'XiaoWangZi'}]>
    return render(request, "index.html")

如何进行ORM多表操作

2.2.3.2基于双下划线的跨表查询--多对多查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 多对多查询:查询SanGuo这本书的所有作者的名字
    # 返回值:queryset对象
    # 方式一:正向查询
    ret1 = Book.objects.filter(title="SanGuo").values("authors__name")
    print(ret1)  # <QuerySet [{'authors__name': 'vita'}, {'authors__name': 'lili'}]>
    # 方式二:反向查询
    ret2 = Author.objects.filter(book__title="SanGuo").values("name")
    print(ret2)  # <QuerySet [{'name': 'vita'}, {'name': 'lili'}]>
    return render(request, "index.html")

如何进行ORM多表操作

2.2.3.3基于双下划线的跨表查询--一对一查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 一对一查询:查询vita的手机号
    # 返回值queryset对象
    # 方式一:正向查询
    ret1 = Author.objects.filter(name="vita").values("authorDetail__telephone")
    print(ret1)  # <QuerySet [{'authorDetail__telephone': 112233}]>
    # 方式二:反向查询
    ret2 = AuthorDetail.objects.filter(author__name="vita").values("telephone")
    print(ret2)  # <QuerySet [{'telephone': 112233}]>
    return render(request, "index.html")

如何进行ORM多表操作

2.2.3.4基于双下划线的跨多表查询
from django.shortcuts import render
from app1.models import *
def index(request):
    # 手机号以11开头的作者出版过的书籍名称以及出版社的名称
    ret1 = Author.objects.filter(authorDetail__telephone__startswith="11").values("book__title","book__publish__name")
    print(ret1)
    ret2 = AuthorDetail.objects.filter(telephone__startswith="11").values("author__book__title","author__book__publish__name")
    print(ret2)
    ret3 = Book.objects.filter(authors__authorDetail__telephone__startswith="11").values("title","publish__name")
    print(ret3)
    return render(request, "index.html")

如何进行ORM多表操作

2.2.4聚合与分组查询

2.2.4.1aggregate聚合查询
返回值是字典
from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 查询所有书籍的平均价格
    # 返回值是字典
    ret = Book.objects.filter(publishDate__year=2012).aggregate(avg_price=Avg("price"),max_price=Max("price"),min_price=Min("price"))
    print(ret)  # {'avg_price': Decimal('100.000000'), 'max_price': Decimal('100.00'), 'min_price': Decimal('100.00')}
    return render(request, "index.html")

如何进行ORM多表操作

2.2.4.2annotate分组查询--单表分组
# annotate分组查询
# 单表分组查询的ORM语法: 单表模型.objects.values("group by的字段").annotate(聚合函数("统计字段"))
# 返回值为queryset对象
# 补充知识点:
    #
    # ret=Emp.objects.all()
    # print(ret)  # select * from emp
    # ret=Emp.objects.values("name")
    # print(ret)  # select name from emp
    # 单表下按照id分组,没有任何意义,这里all()就包含了所有字段,包含了主键id,id是唯一的,按照该字段分组没有任何意义
    # Emp.objects.all().annotate(avg_salary=Avg("salary"))
from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 查询每种价格的书的价格和数量
    # ret = Book.objects.values("price").annotate(book_count = Count("nid").values("title")
    # 单表分组时,最后加values()是又加了一个分组字段,不是取出字段值
    ret = Book.objects.values("price").annotate(book_count = Count("nid"))
    print(ret)  # <QuerySet [{'price': Decimal('100.00'), 'book_count': 2}, {'price': Decimal('120.00'), 'book_count': 3}]>
    return render(request, "index.html")

如何进行ORM多表操作

2.2.4.3annotate分组查询--多表分组
from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 查询每一个出版社的名称以及出版的书籍数
    # 反向查询
    ret1 = Publish.objects.values("name").annotate(book_count=Count("book__nid"))
    print(ret1) # <QuerySet [{'name': 'AA_publish', 'book_count': 4}, {'name': 'BB_publish', 'book_count': 1}]>
    # 正向查询
    ret2 = Book.objects.values("publish__name").annotate(book_count=Count("nid"))
    print(ret2) # <QuerySet [{'publish__name': 'AA_publish', 'book_count': 4}, {'publish__name': 'BB_publish', 'book_count': 1}]>
    # 正向查询,最后values取值
    ret3 = Book.objects.values("publish__nid").annotate(book_count=Count("nid")).values("publish__name","book_count")
    print(ret3) # <QuerySet [{'publish__name': 'AA_publish', 'book_count': 4}, {'publish__name': 'BB_publish', 'book_count': 1}]>
    return render(request, "index.html")

如何进行ORM多表操作

from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 总结 跨表的分组查询的模型:
    # 每一个后表模型.objects.values("pk").annotate(聚合函数(关联表__统计字段))
    # pk为主键
    # 1.查询每一个作者的名字以及出版过的书籍的最高价格
    ret1 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
    print(ret1)
    # 2.查询每一个书籍的名称以及对应的作者数
    ret2 = Book.objects.values("pk").annotate(author_count = Count("authors__nid")).values("title","author_count")
    print(ret2)
    return render(request, "index.html")

如何进行ORM多表操作

from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 查询每一个出版社的名称以及出版社的书籍个数
    # 三种方式:
    ret1=Publish.objects.values("nid").annotate(c=Count("book__title")).values("name","email","c")
    print(ret1)
    ret2=Publish.objects.all().annotate(c=Count("book__title")).values("name","c","city")
    print(ret2)
    ret3 = Publish.objects.annotate(c=Count("book__title")).values("name", "c", "city")
    print(ret3)
    return render(request, "index.html")

如何进行ORM多表操作

from django.shortcuts import render
from django.db.models import Avg,Max,Min,Count
from app1.models import *
def index(request):
    # 统计每一本以S开头的书籍的作者个数
    ret1 = Book.objects.filter(title__startswith="S").values("pk").annotate(author_count = Count("authors__nid")).values("title","author_count")
    print(ret1)
    # 统计不止一个作者的图书
    ret2 = Book.objects.values("pk").annotate(author_count = Count("authors__nid")).filter(author_count__gt=1).values("title","author_count")
    print(ret2)
    return render(request, "index.html")

如何进行ORM多表操作

2.2.5F查询与Q查询

2.2.5.1F查询
from django.shortcuts import render
from django.db.models import F,Q
from app1.models import *
def index(request):
    # 1.F查询,两个字段值作比较
    ret1 = Book.objects.filter(price__gt=F("publish_id"))
    print(ret1)
    # 2.F查询与常数之间的加减乘除和取模
    ret2 = Book.objects.filter(price__gt=F("publish_id")*100)
    print(ret2)
    # 3.支持批量更新
    Book.objects.all().update(price=F("price")+30)
    return render(request, "index.html")

如何进行ORM多表操作

2.2.5.2Q查询
from django.shortcuts import render
from django.db.models import F,Q
from app1.models import *
def index(request):
    # 1.Q查询可以用于“或”查询,filter()方法是“and”查询
    ret1 =Book.objects.filter(Q(authors__name="vita")|Q(authors__name="lili"))
    print(ret1)
    # 2.可以组合&和|以及~(取反)
    # 作者名是vita,age!=23
    ret2 = Book.objects.filter(Q(authors__name="vita")&~Q(authors__age=23))
    print(ret2)
    # 3.查询函数可以混合使用Q对象和关键字参数。关键字参数要放在最后面
    ret3 = Book.objects.filter(Q(authors__age=23)|Q(publishDate__year=2012),title__startswith="S")
    print(ret3)
    return render(request, "index.html")

如何进行ORM多表操作

上述内容就是如何进行ORM多表操作,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注行业资讯频道。

内容来源网络,如有侵权,联系删除,本文地址:https://www.230890.com/zhan/117462.html

(0)

相关推荐

  • 如何用TopN算法在10亿个整数中找出前1000个最大的数

    技术如何用TopN算法在10亿个整数中找出前1000个最大的数如何用TopN算法在10亿个整数中找出前1000个最大的数,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决

    攻略 2021年10月21日
  • 实验二 数组、指针和c++标准库

    技术实验二 数组、指针和c++标准库 实验二 数组、指针和c++标准库实验任务5
    Info.hpp#ifndef INFO_HPP
    #define INFO_hpp#includeiostream
    #i

    礼包 2021年11月1日
  • 适用于Python的编写工具有哪些

    技术适用于Python的编写工具有哪些本篇内容主要讲解“适用于Python的编写工具有哪些”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“适用于Python的编写工具有哪些”吧

    攻略 2021年11月3日
  • 如何理解Oracle 12c CDB的ADG

    技术如何理解Oracle 12c CDB的ADG这篇文章将为大家详细讲解有关如何理解Oracle 12c CDB的ADG,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。实验

    攻略 2021年11月29日
  • PHP实现交换两个整型变量的方法有哪些

    技术PHP实现交换两个整型变量的方法有哪些这篇文章主要介绍“PHP实现交换两个整型变量的方法有哪些”,在日常操作中,相信很多人在PHP实现交换两个整型变量的方法有哪些问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操

    攻略 2021年11月16日
  • C++为什么不要拿着锁调用未知代码

    技术C++为什么不要拿着锁调用未知代码本篇内容主要讲解“C++为什么不要拿着锁调用未知代码”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“C++为什么不要拿着锁调用未知代码”吧

    攻略 2021年11月25日