您好,登錄后才能下訂單哦!
環境:
根據關系創建表
首先建立django項目,編輯models.py 文件
models.py
from django.db import models # Create your models here. class Publish(models.Model): # id 如果不寫,會自動生成,名字叫做nid,并且自增 # 數據庫不同,可能自動生成的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 # 一對一的關系: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) # 浮點型,共5位,小數部分是2位 price=models.DecimalField(max_digits=5,decimal_places=2) # to= 關聯表 to_field= 關聯表中的字段 ,一對多的關系使用 ForeignKey publish=models.ForeignKey(to=Publish,to_field='id') # ManyToManyField 會自動創建第三張表 多對多的關系 authors=models.ManyToManyField(to=Author) def __str__(self): return self.name
遷移數據庫
makemigrations
migrate
在項目中創建Py文件,可以運行在django環境中的代碼
test.py
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pro77_13.settings") import django django.setup() from app01.models import *
一、多表模型創建,一對多的增刪改,與多對多增刪改
在app01_publish表中添加幾條數據
一對多新增數據(接上面的繼續寫)
test.py
# 添加一本北京出版社出版的書 # 第一種方式 # ret=Book.objects.create(name='紅樓夢',price=53.4,publish_id=1) # print(ret.name) # 第二種方式,存對象Publish=出版社對象,存到數據庫是一個id # pk:主鍵,是通過主鍵查找 publish=Publish.objects.filter(pk=2).first() ret=Book.objects.create(name='紅樓夢',price=53.4,publish=publish) print(ret.name)
app01_book表
# 一對多修改數據
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表:
多對多新增數據
首先需要在app01_author與app01_author_details表中添加數據
app01_author_details表:
app01_author表:
test.py
# 為紅樓夢這本書新增一個叫lqz,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,要傳一個列表,列表內可以是 id,也可以是對象
book.authors.set([2,]) # book.authors.set([lqz,])
app01_book_authors表
總結:
1 創建多表模型(詳情見代碼)
#用了OneToOneField和ForeignKey,模型表的字段,后面會自定加_id
# ManyToManyField會自動創建第三張表
# *************重點
# 一對一的關系:OneToOneField
# 一對多的關系:ForeignKey
# 多對多的關系:ManyToManyField
2 添加表記錄
1 一對多新增
-兩種方式:
-publish=對象
-publish_id=id
2 一對多刪除:同單表刪除
3 一對多修改:兩種方式,可以傳對象,可以傳id
4 一對一跟一對多一樣
5 多對多:
-add ----->可以傳對象,可以傳id,可以傳多個
-remove ----->可以傳對象,可以傳id,可以傳多個
-clear ---->沒有參數
-set ----->跟上面不一樣,必須傳列表,列表里面可以是對象,可以是id
二、基于對象的跨表查詢
一對一:
正向 author---關聯字段在author--->authordetail ------> 按字段
反向 authordetail------關聯字段在author--->author -----> 按表名小寫
正向查詢:
lqz = Author.objects.filter(name='lqz').first() egon = Author.objects.filter(name='egon').first() book = Book.objects.filter(name='紅樓夢').first() # 查詢lqz作者的手機號 正向查詢 # 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() # 查詢地址是 :手機號 屬于哪位作者的 反向查詢 authordetail=Author_details.objects.filter(phone='1385469823').first() author=authordetail.author print(author.name)
一對多:
正向 book---關聯字段在book--->publish ------> 按字段
反向 publish------關聯字段在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() # # 統計一下條數 books=publish.book_set.all().count() print(books)
多對多:
正向 book---關聯字段在book--->author ------> 按字段.all()
反向 author------關聯字段在book--->book -----> 按表名小寫_set.all()
正向:查詢紅樓夢這本書所有的作者
book=Book.objects.filter(name='紅樓夢').first() book.authors.all() #是所有的作者,是一個queryset對象,可以繼續點 print(book.authors.all())
反向:查詢lqz寫的所有書
lqz=Author.objects.filter(name='lqz').first() books=lqz.book_set.all() print(books)
連續跨表
# 查詢紅樓夢這本書所有的作者的手機號
book=Book.objects.filter(name='紅樓夢').first() authors=book.authors.all() for author in authors: authordetail=author.authordetail_id print(authordetail.phone)
# 基于對象的查詢---是子查詢也就是多次查詢
在終端打印出sql語句
需要要settings.py中配置以下內容
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()
對應的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;
在查詢結果之后的又一次查詢(子查詢,也就是多次查詢)
print(book.authors.all())
對應的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;
總結:
基于對象的跨表查詢
1 一對一
正向:正向查詢按字段
反向:反向查詢按表名小寫
2 一對多
正向:正向查詢按字段
反向:反向按表名小寫_set.all()
3 多對多
正向:正向查詢按字段
反向查詢:反向按表名小寫_set.all()
4******基于對象的查詢,多次查詢(子查詢)
# 基于雙下劃線的查詢
# 一對一
# 查詢lqz作者的手機號 正向查詢 跨表的話,按字段
# 以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這個作者的手機號
# 正向
ret=Author.objects.filter(name='lqz').values('authordetail_id__phone') print(ret)
#查詢手機號是 1529874130 的作者
ret=Author.objects.filter(authordetail_id__phone='1529874130') print(ret) ret=Author_details.objects.filter(phone='1529874130') print(ret)
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。