如何進行ORM多表操作

本篇文章為大家展示了如何進行ORM多表操作,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

為康縣等地區(qū)用戶提供了全套網頁設計制作服務,及康縣網站建設行業(yè)解決方案。主營業(yè)務為成都網站制作、成都網站設計、康縣網站設計,以傳統(tǒng)方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

1.建表

from django.db import models

# Create your models here.
class AuthorDtail(models.Model):
    nid = models.AutoField(primary_key=True)
    birthday = models.DateField()
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)

class Author(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    # OneToOneField可以建立在兩個模型中的任意一個
    authorDetail = models.OneToOneField(to="AuthorDtail", to_field="nid", on_delete=models.CASCADE)

class Publish(models.Model):
    nid = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

class Book(models.Model):
    nid = models.AutoField(primary_key=True)
    title = models.CharField(max_length=32)
    publishDate = models.DateField()
    price = models.DecimalField(max_digits=9,decimal_places=2)
    # 與Publish建立一對多的關系,外鍵字段建立在多的一方
    publish = models.ForeignKey(to="Publish", to_field="nid", on_delete=models.CASCADE)
    # 多對多,ManyToManyField可以建在兩個模型中的任意一個,自動創(chuàng)建第三張表
    authors = models.ManyToManyField(to="Author")

如何進行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創(chuàng)建的。
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創(chuàng)建的第三方表
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,是根據模型中的元數(shù)據自動生成的,也可以重寫為別的名稱。
2.如果沒有定義AutoField(),默認會創(chuàng)建id字段,為主鍵。
3.對于外鍵字段,Django會在字段上添加"_id"來設置列名。
4.Django會根據settings中指定的數(shù)據庫類型來使用相應的SQL語句。
5.要在INSTALL_APPS中設置models.py所在的應用名稱
6.外鍵字段 ForeignKey 有一個 null=True 的設置(它允許外鍵接受空值 NULL),你可以賦給它空值 None 。

2.多表ORM的增刪改查

2.1插入數(shù)據

如何進行ORM多表操作

2.1.1一對多插入數(shù)據

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的區(qū)別。
    # 可以發(fā)現(xiàn),
    # publish是一個對象,可以通過publish調用相應Publish表中的字段數(shù)據
    # 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多對多插入數(shù)據

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()
    # 與本書關聯(lián)的所有作者信息集合,是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()      # 將某個特定的對象從被關聯(lián)對象集合中去除。    ======   book_obj.authors.remove(*[])
book_obj.authors.clear()       #清空被關聯(lián)對象集合
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中設置的關聯(lián)字段,即Author類中的authorDetail,Book類中的publish和author。
(一對多,多對多)反向查詢按表名小寫_set----因為是多個數(shù)據,所以使用set,集合之意。
(一對一)反向查詢按表名小寫----因為只有一條對應數(shù)據,所以無set。

2.2.2基于對象查詢----子查詢

守則:
正想查詢按字段
反向查詢按表名
詳解:
正向查詢按字段,models.py中設置的關聯(lián)字段,即Author類中的authorDetail,Book類中的publish和author。
(一對多,多對多)反向查詢按表名小寫_set----因為是多個數(shù)據,所以使用set,集合之意。
(一對一)反向查詢按表名小寫----因為只有一條對應數(shù)據,所以無set。
2.2.2.1準備數(shù)據

如何進行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(聚合函數(shù)("統(tǒng)計字段"))
# 返回值為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):
    # 查詢每種價格的書的價格和數(shù)量
    # 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):
    # 查詢每一個出版社的名稱以及出版的書籍數(shù)
    # 反向查詢
    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(聚合函數(shù)(關聯(lián)表__統(tǒng)計字段))
    # pk為主鍵

    # 1.查詢每一個作者的名字以及出版過的書籍的最高價格
    ret1 = Author.objects.values("pk").annotate(max_price = Max("book__price")).values("name","max_price")
    print(ret1)
    # 2.查詢每一個書籍的名稱以及對應的作者數(shù)
    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):
    # 查詢每一個出版社的名稱以及出版社的書籍個數(shù)
    # 三種方式:
    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):
    # 統(tǒng)計每一本以S開頭的書籍的作者個數(shù)
    ret1 = Book.objects.filter(title__startswith="S").values("pk").annotate(author_count = Count("authors__nid")).values("title","author_count")
    print(ret1)
    # 統(tǒng)計不止一個作者的圖書
    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查詢與常數(shù)之間的加減乘除和取模
    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.查詢函數(shù)可以混合使用Q對象和關鍵字參數(shù)。關鍵字參數(shù)要放在最后面
    ret3 = Book.objects.filter(Q(authors__age=23)|Q(publishDate__year=2012),title__startswith="S")
    print(ret3)
    return render(request, "index.html")

如何進行ORM多表操作

上述內容就是如何進行ORM多表操作,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

本文名稱:如何進行ORM多表操作
網頁網址:http://bm7419.com/article26/jjecjg.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供云服務器、移動網站建設定制網站、微信公眾號、自適應網站、企業(yè)網站制作

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

成都網站建設公司