溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

發(fā)布時間:2020-06-18 07:15:38 來源:網(wǎng)絡(luò) 閱讀:505 作者:a120518129 欄目:編程語言

環(huán)境:

根據(jù)關(guān)系創(chuàng)建表八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

首先建立django項目,編輯models.py 文件

models.py

from django.db import models

# Create your models here.
class Publish(models.Model):
    # id 如果不寫,會自動生成,名字叫做nid,并且自增
    # 數(shù)據(jù)庫不同,可能自動生成的id 名字也不太一樣。
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)
    email = models.EmailField()

class Author_details(models.Model):
    phone = models.CharField(max_length=16)
    sex = models.IntegerField

class Author(models.Model):
    name = models.CharField(max_length=32)
    addr = models.CharField(max_length=64)
    # 使用了 OneToOneField 與 ForeignKey,模型表的字段,后面會自動加_id
    # 一對一的關(guān)系:OneToOneField
    authordetail_id = models.OneToOneField(to='Author_details', to_field='id')
    def __str__(self):
            return self.name

class Book(models.Model):
    name=models.CharField(max_length=16)
    # 浮點(diǎn)型,共5位,小數(shù)部分是2位
    price=models.DecimalField(max_digits=5,decimal_places=2)
    # to= 關(guān)聯(lián)表    to_field= 關(guān)聯(lián)表中的字段 ,一對多的關(guān)系使用 ForeignKey
    publish=models.ForeignKey(to=Publish,to_field='id')
    # ManyToManyField 會自動創(chuàng)建第三張表   多對多的關(guān)系
    authors=models.ManyToManyField(to=Author)
    def __str__(self):
            return self.name

遷移數(shù)據(jù)庫

makemigrations

migrate

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

在項目中創(chuàng)建Py文件,可以運(yùn)行在django環(huán)境中的代碼

test.py

import os
if __name__ == '__main__':
    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pro77_13.settings")
    import django
    django.setup()

    from app01.models import *

一、多表模型創(chuàng)建,一對多的增刪改,與多對多增刪改

在app01_publish表中添加幾條數(shù)據(jù)

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

一對多新增數(shù)據(jù)(接上面的繼續(xù)寫)

test.py

# 添加一本北京出版社出版的書
# 第一種方式
# ret=Book.objects.create(name='紅樓夢',price=53.4,publish_id=1)
# print(ret.name)

# 第二種方式,存對象Publish=出版社對象,存到數(shù)據(jù)庫是一個id
# pk:主鍵,是通過主鍵查找
publish=Publish.objects.filter(pk=2).first()
ret=Book.objects.create(name='紅樓夢',price=53.4,publish=publish)
print(ret.name)

app01_book表

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

# 一對多修改數(shù)據(jù)

test.py

方式一:

book=Book.objects.get(pk=1)
# 解釋:book.publish=出版社對象
book.publish_id=2
book.save()

app01_book表:

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

方式二:

# 解釋:book=Book.objects.filter(pk=1).update(publish=出版社對象)
book=Book.objects.filter(pk=1).update(publish_id=1)

app01_book表:

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

多對多新增數(shù)據(jù)

首先需要在app01_author與app01_author_details表中添加數(shù)據(jù)

app01_author_details表:

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

app01_author表:

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

test.py

# 為紅樓夢這本書新增一個叫l(wèi)qz,egon的作者

方式一:

test.py

lqz=Author.objects.filter(name='lqz').first()
egon=Author.objects.filter(name='egon').first()
book=Book.objects.filter(name='紅樓夢').first()
# # add 添加多個對象
book.authors.add(lqz,egon)

這樣就可以在中間表里看見(app01_book_authors:中間表)

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

方式二:

# add添加作者id
book.authors.add(1,2)

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

# 刪除 remove,可以傳對象,可以傳id,可以傳多個,不要混著用

lqz=Author.objects.filter(name='lqz').first()
egon=Author.objects.filter(name='egon').first()
book=Book.objects.filter(name='紅樓夢').first()
book.authors.remove(lqz)
# 也可以
# book.authors.remove(1,2)
# clear清空所有
# book.authors.clear()

set,要傳一個列表,列表內(nèi)可以是 id,也可以是對象

book.authors.set([2,])
# book.authors.set([lqz,])

app01_book_authors表

八、多表模型操作,基于對象的跨表查詢,基于雙下劃線的跨表查詢

總結(jié):

1 創(chuàng)建多表模型(詳情見代碼)
        #用了OneToOneField和ForeignKey,模型表的字段,后面會自定加_id
        # ManyToManyField會自動創(chuàng)建第三張表
        # *************重點(diǎn)
        # 一對一的關(guān)系:OneToOneField
        # 一對多的關(guān)系:ForeignKey
        # 多對多的關(guān)系:ManyToManyField
        
    2 添加表記錄
        1 一對多新增
            -兩種方式:
                -publish=對象
                -publish_id=id
        2 一對多刪除:同單表刪除
        3 一對多修改:兩種方式,可以傳對象,可以傳id
        4 一對一跟一對多一樣
        5 多對多:
            -add  ----->可以傳對象,可以傳id,可以傳多個
            -remove  ----->可以傳對象,可以傳id,可以傳多個
            -clear  ---->沒有參數(shù)
            -set   ----->跟上面不一樣,必須傳列表,列表里面可以是對象,可以是id

二、基于對象的跨表查詢

一對一:
    正向   author---關(guān)聯(lián)字段在author--->authordetail   ------>  按字段
    反向   authordetail------關(guān)聯(lián)字段在author--->author  -----> 按表名小寫

正向查詢:

lqz = Author.objects.filter(name='lqz').first()
egon = Author.objects.filter(name='egon').first()
book = Book.objects.filter(name='紅樓夢').first()
# 查詢lqz作者的手機(jī)號   正向查詢
# author = Author.objects.filter(name='lqz').first()
# authordetail = author.authordetail_id
# print(authordetail.phone)

反向查詢:

lqz = Author.objects.filter(name='lqz').first()
egon = Author.objects.filter(name='egon').first()
book = Book.objects.filter(name='紅樓夢').first()
# 查詢地址是 :手機(jī)號 屬于哪位作者的   反向查詢
authordetail=Author_details.objects.filter(phone='1385469823').first()
author=authordetail.author
print(author.name)

一對多:

    正向   book---關(guān)聯(lián)字段在book--->publish   ------>  按字段
   反向   publish------關(guān)聯(lián)字段在book--->book  -----> 按表名小寫_set.all()

正向查詢:查詢紅樓夢這本書的出版社郵箱

book=Book.objects.filter(name='紅樓夢').first()
# # book.publish  就是出版社對象
publish=book.publish
print(publish.email)

反向查詢:查詢地址是北京 的出版社出版的圖

publish=Publish.objects.filter(addr='北京').first()
# # publish.book_set.all()  拿出所有的圖書
# books=publish.book_set.all()
# # 統(tǒng)計一下條數(shù)
books=publish.book_set.all().count()
print(books)

多對多:

正向   book---關(guān)聯(lián)字段在book--->author   ------>  按字段.all()
反向   author------關(guān)聯(lián)字段在book--->book  -----> 按表名小寫_set.all()

正向:查詢紅樓夢這本書所有的作者

book=Book.objects.filter(name='紅樓夢').first()
book.authors.all()  #是所有的作者,是一個queryset對象,可以繼續(xù)點(diǎn)
print(book.authors.all())

反向:查詢lqz寫的所有書

lqz=Author.objects.filter(name='lqz').first()
books=lqz.book_set.all()
print(books)

連續(xù)跨表
# 查詢紅樓夢這本書所有的作者的手機(jī)號

book=Book.objects.filter(name='紅樓夢').first()
authors=book.authors.all()
for author in authors:
    authordetail=author.authordetail_id
    print(authordetail.phone)

# 基于對象的查詢---是子查詢也就是多次查詢

在終端打印出sql語句

需要要settings.py中配置以下內(nèi)容

LOGGING = {
    'version': 1,
    'disable_existing_loggers': False,
    'handlers': {
        'console':{
            'level':'DEBUG',
            'class':'logging.StreamHandler',
        },
    },
    'loggers': {
        'django.db.backends': {
            'handlers': ['console'],
            'propagate': True,
            'level':'DEBUG',
        },
    }
}

test.py

book=Book.objects.filter(name='紅樓夢').first()

對應(yīng)的sql語句:

SELECT
    `app01_book`.`id`,
    `app01_book`.`name`,
    `app01_book`.`price`,
    `app01_book`.`publish_id` 
FROM
    `app01_book` 
WHERE
    `app01_book`.`name` = '紅樓夢' 
ORDER BY
    `app01_book`.`id` ASC 
    LIMIT 1;

在查詢結(jié)果之后的又一次查詢(子查詢,也就是多次查詢)

print(book.authors.all())

對應(yīng)的sql語句:

SELECT
    `app01_author`.`id`,
    `app01_author`.`name`,
    `app01_author`.`addr`,
    `app01_author`.`authordetail_id_id` 
FROM
    `app01_author`
    INNER JOIN `app01_book_authors` ON ( `app01_author`.`id` = `app01_book_authors`.`author_id` ) 
WHERE
    `app01_book_authors`.`book_id` = 1 
    LIMIT 21;

總結(jié):

基于對象的跨表查詢
        1 一對一
            正向:正向查詢按字段
            反向:反向查詢按表名小寫
        2 一對多
            正向:正向查詢按字段

            反向:反向按表名小寫_set.all()
        3 多對多
            正向:正向查詢按字段
            反向查詢:反向按表名小寫_set.all()
        4******基于對象的查詢,多次查詢(子查詢)

# 基于雙下劃線的查詢

# 一對一
# 查詢lqz作者的手機(jī)號   正向查詢  跨表的話,按字段
# 以author表作為基表

ret=Author.objects.filter(name='lqz').values('authordetail_id__phone')
print(ret)

# 以authordetail作為基表 反向查詢,按表名小寫  跨表的話,用表名小寫

ret=Author_details.objects.filter(author__name='lqz').values('phone')
print(ret)

# 查詢lqz這個作者的手機(jī)號
# 正向

ret=Author.objects.filter(name='lqz').values('authordetail_id__phone')
print(ret)

#查詢手機(jī)號是 1529874130 的作者

ret=Author.objects.filter(authordetail_id__phone='1529874130')
print(ret)

ret=Author_details.objects.filter(phone='1529874130')
print(ret)



向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI