在進行通常操做時先配置一下參數,使得咱們能夠直接在Django頁面中運行咱們的測試腳本python
須要在settings中配置:mysql
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'tabledatabase', 'USER':'root', 'PASSWORD':'root', 'HOST':'127.0.0.1', 'PORT':3306, 'CHARSET':'utf8', 'ATOMIC_REQUEST': True, 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } } } ''' 'NAME':要鏈接的數據庫,鏈接前須要建立好 'USER':鏈接數據庫的用戶名 'PASSWORD':鏈接數據庫的密碼 'HOST':鏈接主機,默認本機 'PORT':端口 默認3306 'CHARSET':'utf8',字符編碼默認utf8 'ATOMIC_REQUEST': True, 設置爲True統一個http請求對應的全部sql都放在一個事務中執行(要麼全部都成功,要麼全部都失敗)。 是全局性的配置, 若是要對某個http請求放水(而後自定義事務),能夠用non_atomic_requests修飾器 'OPTIONS': { "init_command": "SET storage_engine=MyISAM", } 設置建立表的存儲引擎爲MyISAM,INNODB '''
注意1:NAME即數據庫的名字,在mysql鏈接前該數據庫必須已經建立,而上面的sqlite數據庫下的db.sqlite3則是項目自動建立 USER和PASSWORD分別是數據庫的用戶名和密碼。設置完後,再啓動咱們的Django項目前,咱們須要激活咱們的mysql。而後,啓動項目,會報錯:no module named MySQLdb 。這是由於django默認你導入的驅動是MySQLdb,但是MySQLdb 對於py3有很大問題,因此咱們須要的驅動是PyMySQL 因此,咱們只須要找到項目名文件下的__init__,在裏面寫入:linux
import pymysql pymysql.install_as_MySQLdb()
最後經過兩條數據庫遷移命令便可在指定的數據庫中建立表 :git
python manage.py makemigrations python manage.py migrate
注意2:確保配置文件中的INSTALLED_APPS中寫入咱們建立的app名稱sql
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', "app01" ]
注意3:若是報錯以下:數據庫
django.core.exceptions.ImproperlyConfigured: mysqlclient 1.3.3 or newer is required; you have 0.7.11.None
MySQLclient目前只支持到python3.4,所以若是使用的更高版本的python,須要修改以下:django
經過查找路徑C:\Programs\Python\Python36-32\Lib\site-packages\Django-2.0-py3.6.egg\django\db\backends\mysql
這個路徑裏的文件把session
if version < (1, 3, 3): raise ImproperlyConfigured("mysqlclient 1.3.3 or newer is required; you have %s" % Database.__version__)
註釋掉就能夠了app
import os if __name__ == '__main__': os.environ.setdefault("DJANGO_SETTINGS_MODULE", "untitled15.settings") import django django.setup() from app01 import models books = models.Book.objects.all() print(books)
這樣就能夠直接運行你的test.py文件來運行測試測試
若是你想知道你對數據庫進行操做時,Django內部究竟是怎麼執行它的sql語句時能夠加下面的配置來查看
在Django項目的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', }, } }
配置好以後,再執行任何對數據庫進行操做的語句時,會自動將Django執行的sql語句打印到pycharm終端上
補充:
除了配置外,還能夠經過一點.query便可查看查詢語句,具體操做以下:
操做下面的操做以前,咱們實現建立好了數據表,這裏主要演示下面的操做,再也不細講建立準備過程
python manage.py makemigrations python manage.py migrate
.models.py from django.db import models # Create your models here. from django.db import models class Book(models.Model): title = models.CharField(max_length=32) price = models.DecimalField(max_digits=8, decimal_places=2) publish_data = models.DateField() def __str__(self): return self.title
tests.py import os if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "onetable.settings") import django django.setup()
from oneapp import models import datetime 增長 res = models.Book.objects.create(title='python',price=121,publish_data=datetime.datetime.now()) print(res) res1 = models.Book.objects.create(title='python',price=121,publish_data='2019-5-4') print(res1) book_obj = models.Book(title='math',price=120,publish_data='2019-4-7') book_obj.save() 刪除 res = models.Book.objects.filter(title='python').delete() print(res) 修改 res = models.Book.objects.filter(pk=3).update(title='linux') print(res) book_obj= models.Book.objects.filter(pk=5).first() book_obj.title = 'Go' book_obj.save()
<1> all(): 查詢全部結果
1 res = models.Book.objects.all() print(res)
**<2> filter(**kwargs): 它包含了與所給篩選條件相匹配的對象**
2 res = models.Book.objects.filter() print(res) res = models.Book.objects.filter(title='python') print(res.first().price)
**<3> get(**kwargs): 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。**
3 res = models.Book.objects.get(title='python') print(res)
**<4> exclude(**kwargs): 它包含了與所給篩選條件不匹配的對象**
4 res = models.Book.objects.exclude(id=4) print(res)
<5> values(*field): 返回一個ValueQuerySet——一個特殊的
QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列
5 res = models.Book.objects.values('title') print(res)
<6> values_list(*field): 它與values()很是類似,它返回的是一個元組序列,values返回的是一個字典序列
6 res = models.Book.objects.values_list('title') print(res,type(res.first()))
<7> order_by(*field): 對查詢結果排序
7 res = models.Book.objects.order_by('price')#默認是升序 print(res) res = models.Book.objects.order_by('-price') print(res)
<8> reverse(): 對查詢結果反向排序,請注意reverse()一般只能在具備已定義順序的QuerySet上調用(在model類的Meta中指定ordering或調用order_by()方法)。不能傳值
8 print(models.Book.objects.order_by('price')) res = models.Book.objects.order_by('price').reverse() print(res)
<9> distinct(): 從返回結果中剔除重複紀錄(若是你查詢跨越多個表,可能在計算QuerySet時獲得重複的結果。此時可使用distinct(),注意只有在PostgreSQL中支持按字段去重。)不能傳值
9 res = models.Book.objects.all().distinct() print(res)
<10> count(): 返回數據庫中匹配查詢(QuerySet)的對象數量。不能傳值
10 res = models.Book.objects.all().count() print(res)
<11> first(): 返回第一條記錄
11 res = models.Book.objects.all().first() print(res)
<12> last(): 返回最後一條記錄
12 res = models.Book.objects.all().last() print(res)
<13> exists(): 若是QuerySet包含數據,就返回True,不然返回False,不能傳值
13 res = models.Book.objects.all().exists() print(res)
返回QuerySet對象的方法有
all()查詢全部結果
filter()它包含了與所給篩選條件相匹配的對象,不加條件的時候返回全部。和all()相同。
exclude()它包含了與所給篩選條件不匹配的對象
order_by()對查詢結果排序('-id')
reverse()對查詢結果反向排序,對查詢結果反向排序,請注意reverse()一般只能在具備已定義順序的QuerySet上調用(在model類的Meta中指定ordering或調用order_by()方法)。
distinct()從返回結果中剔除重複紀錄
特殊的QuerySet
values() 返回一個可迭代的字典序列,返回一個ValueQuerySet——一個特殊的QuerySet,運行後獲得的並非一系列model的實例化對象,而是一個可迭代的字典序列,獲取全部的值,以字典的形式打印
values_list() 返回一個可迭代的元祖序列,它與values()很是類似,它返回的是一個元組序列。
返回具體對象的
get() 返回與所給篩選條件相匹配的對象,返回結果有且只有一個,若是符合篩選條件的對象超過一個或者沒有都會拋出錯誤。
first() 返回第一條記錄
last()返回最後一條記錄
返回數字的方法有
count()返回數據庫中匹配查詢(QuerySet)的對象數量。
返回布爾值的方法有:
exists()若是QuerySet包含數據,就返回True,不然返回False
不能傳值的有
count(),first(),last(),exists(),distinct(),all()
查詢價格大於200的書籍 res = models.Book.objects.filter(price__gt=200) 查詢價格小於200的書籍 res = models.Book.objects.filter(price__lt=200) 查詢價格大於或者等於200的書籍 res = models.Book.objects.filter(price__gte=200) res1 = models.Book.objects.filter(price__lte=200) 價格是200 或者是123.23 或者666.66 res = models.Book.objects.filter(price__in=[200,123.23,666.66]) 價格在200 到700之間的書籍 res = models.Book.objects.filter(price__range=(200,666.66))# 顧頭不顧尾 res = models.Book.objects.filter(price__range=[10, 200])
# 模糊匹配 """ like % _ """ 查詢書籍名稱中包含p的 res = models.Book.objects.filter(title__contains='p') # 區分大小寫 忽略大小寫 res = models.Book.objects.filter(title__icontains='p') # 忽略大小寫 查詢書籍名稱是以三開頭的書籍 res = models.Book.objects.filter(title__startswith='p') res1 = models.Book.objects.filter(title__endswith='h') print(res1) 查詢出版日期是2019年的書籍 res = models.Book.objects.filter(publish_date__year='2019') 查詢出版日期是10月的書籍 res = models.Book.objects.filter(publish_date__month='10')
Book.objects.filter(pub_date__year=2012) date字段還能夠: models.Book.objects.filter(first_day__year=2017) date字段能夠經過在其後加__year,__month,__day等來獲取date的特色部分數據 # date # Book.objects.filter(pub_date__date=datetime.date(2005, 1, 1)) # Book.objects.filter(pub_date__date__gt=datetime.date(2005, 1, 1)) # year # # Book.objects.filter(pub_date__year=2005) # Book.objects.filter(pub_date__year__gte=2005) # month # # Book.objects.filter(pub_date__month=12) # Book.objects.filter(pub_date__month__gte=6) # day # # Book.objects.filter(pub_date__day=3) # Book.objects.filter(pub_date__day__gte=3) # week_day # # Book.objects.filter(pub_date__week_day=2) # Book.objects.filter(pub_date__week_day__gte=2) 須要注意的是在表示一年的時間的時候,咱們一般用52周來表示,由於天數是不肯定的,老外就是按周來計算薪資的哦~
語法:
對象.關聯字段.字段
要點:先拿到對象,再經過對象去查對應的外鍵字段,分兩步
示例:
book_obj = models.Book.objects.first() # 第一本書對象(第一步) print(book_obj.publisher) # 獲得這本書關聯的出版社對象 print(book_obj.publisher.name) # 獲得出版社對象的名稱
語法:
關聯字段**__****字段**
要點:利用Django給咱們提供的神奇的雙下劃線查找方式
示例:
models.Book.objects.all().values("publisher__name") #拿到全部數據對應的出版社的名字,神奇的下劃線幫咱們誇表查詢
語法:
obj.表名_set
要點:先拿到外鍵關聯多對一,一中的某個對象,因爲外鍵字段設置在多的一方,因此這裏仍是借用Django提供的雙下劃線來查找
示例:
publisher_obj = models.Publisher.objects.first() # 找到第一個出版社對象 books = publisher_obj.book_set.all() # 找到第一個出版社出版的全部書 titles = books.values_list("title") # 找到第一個出版社出版的全部書的書名
結論:若是想經過一的那一方去查找多的一方,因爲外鍵字段不在一這一方,因此用__set來查找便可
語法:
**表名__字段**
要點:直接利用雙下滑線完成誇表操做
titles = models.Publisher.objects.values("book__title")
"關聯管理器"是在一對多或者多對多的關聯上下文中使用的管理器。
它存在於下面兩種狀況:
簡單來講就是在多對多表關係而且這一張多對多的關係表是有Django自動幫你建的狀況下,下面的方法纔可以使用。
create()
建立一個關聯對象,並自動寫入數據庫,且在第三張雙方的關聯表中自動新建上雙方對應關係。
models.Author.objects.first().book_set.create(title="偷塔祕籍") 上面這一句幹了哪些事兒: 1.由做者表中的一個對象跨到書籍比表 2.新增名爲偷塔祕籍的書籍並保存 3.到做者與書籍的第三張表中新增二者之間的多對多關係並保存
add()
add() 括號內既能夠傳數字也能夠傳數據對象,而且都支持傳多個
把指定的model對象添加到第三張關聯表中。
添加對象,添加id
book_obj = models.Book.objects.filter(pk=3).first() print(book_obj.authors) # 就至關於 已經在書籍和做者的關係表了 book_obj.authors.add(1) book_obj.authors.add(2,3) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.add(author_obj) book_obj.authors.add(author_obj,author_obj1)
set()
set() 括號內 既能夠傳數字也傳對象
而且也是支持傳多個的
可是須要注意 括號內必須是一個可迭代對象
更新某個對象在第三張表中的關聯對象。不一樣於上面的add是添加,set至關於重置,能夠添加對象和id
book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.set([3,]) book_obj.authors.set([1,3]) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.set((author_obj,)) book_obj.authors.set((author_obj,author_obj1))
remove()
remove() 括號內 既能夠傳數字也傳對象 而且也是支持傳多個的
從關聯對象集中移除執行的model對象(移除對象在第三張表中與某個關聯對象的關係)
book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.remove(2) book_obj.authors.remove(1,2) author_obj = models.Author.objects.filter(pk=1).first() author_obj1 = models.Author.objects.filter(pk=2).first() book_obj.authors.remove(author_obj) book_obj.authors.remove(author_obj,author_obj1)
clear()
clear()括號內不須要傳任何參數 直接清空當前書籍對象全部的記錄
從關聯對象集中移除一切對象。(移除全部與對象相關的關係信息)
book_obj = models.Book.objects.filter(pk=3).first() book_obj.authors.clear()
注意:
對於ForeignKey對象,clear()和remove()方法僅在null=True時存在。
舉個例子:
ForeignKey字段沒設置null=True時,
class Book(models.Model): title = models.CharField(max_length=32) publisher = models.ForeignKey(to=Publisher)
沒有clear()和remove()方法:
>>> models.Publisher.objects.first().book_set.clear() Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'RelatedManager' object has no attribute 'clear'
當ForeignKey字段設置null=True時,
class Book(models.Model): name = models.CharField(max_length=32) publisher = models.ForeignKey(to=Class, null=True)
此時就有clear()和remove()方法:
>>> models.Publisher.objects.first().book_set.clear()
再次強調:
實例:咱們來假定下面這些概念,字段和關係
做者模型:一個做者有姓名和年齡。
做者詳細模型:把做者的詳情放到詳情表,包含生日,手機號,家庭住址等信息。做者詳情模型和做者模型之間是一對一的關係(one-to-one)
出版商模型:出版商有名稱,所在城市以及email。
書籍模型: 書籍有書名和出版日期,一本書可能會有多個做者,一個做者也能夠寫多本書,因此做者和書籍的關係就是多對多的關聯關係(many-to-many);一本書只應該由一個出版商出版,因此出版商和書籍是一對多關聯關係(one-to-many)。
注意:關聯字段與外鍵約束沒有必然的聯繫(建管理字段是爲了進行查詢,建約束是爲了避免出現髒數據)
在Models建立以下模型
class Book(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) price = models.DecimalField(max_digits=5, decimal_places=2) publish_date = models.DateField() # 閱讀數 # reat_num=models.IntegerField(default=0) # 評論數 # commit_num=models.IntegerField(default=0) publish = models.ForeignKey(to='Publish',to_field='nid',on_delete=models.CASCADE) authors=models.ManyToManyField(to='Author') def __str__(self): return self.name class Author(models.Model): nid = models.AutoField(primary_key=True) name = models.CharField(max_length=32) age = models.IntegerField() author_detail = models.OneToOneField(to='AuthorDatail',to_field='nid',unique=True,on_delete=models.CASCADE) class AuthorDatail(models.Model): nid = models.AutoField(primary_key=True) telephone = models.BigIntegerField() birthday = models.DateField() addr = models.CharField(max_length=64) 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()
注意事項:
myapp_modelName
,是根據 模型中的元數據自動生成的,也能夠覆寫爲別的名稱 id
字段是自動添加的"_id"
來建立數據庫中的列名models.py
所在應用的名稱。方式1: publish_obj=Publish.objects.get(nid=1) book_obj=Book.objects.create(title="",publishDate="2012-12-12",price=100,publish=publish_obj) 方式2: book_obj=Book.objects.create(title="",publishDate="2012-12-12",price=100,publish_id=1)
核心:book_obj.publish與book_obj.publish_id是什麼?
關鍵點: 一 book_obj.publish=Publish.objects.filter(id=book_obj.publish_id).first() 二 book_obj.authors.all() 關鍵點:book.authors.all() # 與這本書關聯的做者集合 1 book.id=3 2 book_authors id book_id author_ID 3 3 1 4 3 2 3 author id name 1 alex 2 egon book_obj.authors.all() -------> [alex,egon]
# -----一對多添加 pub=Publish.objects.create(name='egon出版社',email='445676@qq.com',city='山東') print(pub) # 爲book表綁定和publish的關係 import datetime,time now=datetime.datetime.now().__str__() now = datetime.datetime.now().strftime('%Y-%m-%d') print(type(now)) print(now) # 日期類型必須是日期對象或者字符串形式的2018-09-12(2018-9-12),其它形式不行 Book.objects.create(name='海燕3',price=333.123,publish_date=now,publish_id=2) Book.objects.create(name='海3燕3',price=35.123,publish_date='2018/02/28',publish=pub) pub=Publish.objects.filter(nid=1).first() book=Book.objects.create(name='測試書籍',price=33,publish_date='2018-7-28',publish=pub) print(book.publish.name) # 查詢出版了紅樓夢這本書出版社的郵箱 book=Book.objects.filter(name='紅樓夢').first() print(book.publish.email)
# 當前生成的書籍對象 book_obj=Book.objects.create(title="追風箏的人",price=200,publishDate="2012-11-12",publish_id=1) # 爲書籍綁定的作做者對象 yuan=Author.objects.filter(name="yuan").first() # 在Author表中主鍵爲2的紀錄 egon=Author.objects.filter(name="alex").first() # 在Author表中主鍵爲1的紀錄 # 綁定多對多關係,即向關係表book_authors中添加紀錄 book_obj.authors.add(yuan,egon) # 將某些特定的 model 對象添加到被關聯對象集合中。 ======= book_obj.authors.add(*[])
book = Book.objects.filter(name='紅樓夢').first() egon=Author.objects.filter(name='egon').first() lqz=Author.objects.filter(name='lqz').first() # 1 沒有返回值,直接傳對象 book.authors.add(lqz,egon) # 2 直接傳做者id book.authors.add(1,3) # 3 直接傳列表,會打散 book.authors.add(*[1,2]) # 解除多對多關係 book = Book.objects.filter(name='紅樓夢').first() # 1 傳做者id book.authors.remove(1) # 2 傳做者對象 egon = Author.objects.filter(name='egon').first() book.authors.remove(egon) #3 傳*列表 book.authors.remove(*[1,2]) #4 刪除全部 book.authors.clear() # 5 拿到與 這本書關聯的全部做者,結果是queryset對象,做者列表 ret=book.authors.all() # print(ret) # 6 queryset對象,又能夠繼續點(查詢紅樓夢這本書全部做者的名字) ret=book.authors.all().values('name') print(ret) # 以上總結: # (1) # book=Book.objects.filter(name='紅樓夢').first() # print(book) # 在點publish的時候,其實就是拿着publish_id又去app01_publish這個表裏查數據了 # print(book.publish) # (2)book.authors.all()
核心:book_obj.authors.all()是什麼?
多對多關係其它經常使用API:
book_obj.authors.remove() # 將某個特定的對象從被關聯對象集合中去除。 ====== book_obj.authors.remove(*[]) book_obj.authors.clear() #清空被關聯對象集合 book_obj.authors.set() #先清空再設置
ORM跨表查詢 1.子查詢 2.連表查詢 正反向的概念 外鍵字段在誰那兒 由誰查誰就是正向 誰手裏有外鍵字段 誰就是正向查 沒有外鍵字段的就是反向 書籍對象 查 出版社 外鍵字段在書籍 正向查詢 出版社 查 書籍 外鍵字段在書籍 反向查詢 正向查詢按字段 反向查詢按表名小寫 ...
# 1.基於對象的跨表查詢 子查詢 # 1.查詢書籍是python入門的出版社名稱 # book_obj = models.Book.objects.filter(title='python入門').first() # # 正向查詢按字段 # print(book_obj.publish.name) # print(book_obj.publish.addr) # 2.查詢書籍主鍵是6的做者姓名 # book_obj = models.Book.objects.filter(pk=6).first() # # print(book_obj.authors) # app01.Author.None # print(book_obj.authors.all()) # 3.查詢做者是jason的手機號 # author_obj = models.Author.objects.filter(name='jason').first() # print(author_obj.author_detail.phone) # print(author_obj.author_detail.addr) """ 正向查詢 按字段 當該字段所對應的數據有多個的時候 須要加.all() 否者點外鍵字段直接就可以拿到數據對象 """ # 4.查詢出版社是東方出版社出版過的書籍 # publish_obj = models.Publish.objects.filter(name='東方出版社').first() # # print(publish_obj.book_set) # app01.Book.None # print(publish_obj.book_set.all()) # 5.查詢做者是jason寫過的全部的書 # author_obj = models.Author.objects.filter(name='jason').first() # # print(author_obj.book_set) # app01.Book.None # print(author_obj.book_set.all()) # 6.查詢手機號是110的做者 # author_detail_obj = models.AuthorDetail.objects.filter(phone=110).first() # print(author_detail_obj.author) # print(author_detail_obj.author.name) # print(author_detail_obj.author.age) """ 反向查詢按表名小寫 何時須要加_set 當查詢的結果能夠是多個的狀況下 須要加_set.all() 何時不須要加_set 當查詢的結果有且只有一個的狀況下 不須要加任何東西 直接表名小寫便可 """ # 7.查詢書籍是python入門的做者的手機號 # book_obj = models.Book.objects.filter(title='python入門').first() # print(book_obj.authors.all()) # 2.基於雙下劃綫的跨表查詢 連表查詢 """ MySQL left join inner join right join union """ # 1.查詢書籍是python入門的出版社名稱 # 正向 # res = models.Book.objects.filter(title='python入門').values('publish__name') # print(res) # 反向 # res = models.Publish.objects.filter(book__title='python入門').values('name') # print(res) # 2.查詢做者是jason的手機號碼 # 正向 # res1 = models.Author.objects.filter(name='jason').values('author_detail__phone') # print(res1) # 反向 # res = models.AuthorDetail.objects.filter(author__name='jason').values('phone','author__age') # print(res) # 3.查詢手機號是120的做者姓名 # res2 = models.AuthorDetail.objects.filter(phone=120).values('author__name') # print(res2) # res = models.Author.objects.filter(author_detail__phone=120).values('name','author_detail__addr') # print(res) # 4.查詢出版社是東方出版社出版的書籍名稱 # res = models.Publish.objects.filter(name='東方出版社').values('book__title','addr') # print(res) # 5.查詢做者是jason的寫過的書的名字和價格 # res = models.Author.objects.filter(name='jason').values('book__title','book__price') # print(res) # 7.查詢書籍是python入門的做者的手機號 # res = models.Book.objects.filter(title='python入門').values('authors__author_detail__phone') # print(res)
正向查詢(按字段:publish)
# 查詢主鍵爲1的書籍的出版社所在的城市 book_obj=Book.objects.filter(pk=1).first() # book_obj.publish 是主鍵爲1的書籍對象關聯的出版社對象 print(book_obj.publish.city)
反向查詢(按表名:book_set)
publish=Publish.objects.get(name="蘋果出版社") #publish.book_set.all() : 與蘋果出版社關聯的全部書籍對象集合 book_list=publish.book_set.all() for book_obj in book_list: print(book_obj.title)
# 一對多正向查詢 book=Book.objects.filter(name='紅樓夢').first() print(book.publish)#與這本書關聯的出版社對象 print(book.publish.name) # 一對多反向查詢 # 人民出版社出版過的書籍名稱 pub=Publish.objects.filter(name='人民出版社').first() ret=pub.book_set.all() print(ret)
正向查詢(按字段:authorDetail):
egon=Author.objects.filter(name="egon").first() print(egon.authorDetail.telephone)
反向查詢(按表名:author):
# 查詢全部住址在北京的做者的姓名 authorDetail_list=AuthorDetail.objects.filter(addr="beijing") for obj in authorDetail_list: print(obj.author.name)
# 一對一正向查詢 # lqz的手機號 lqz=Author.objects.filter(name='lqz').first() tel=lqz.author_detail.telephone print(tel) # 一對一反向查詢 # 地址在北京的做者姓名 author_detail=AuthorDatail.objects.filter(addr='北京').first() name=author_detail.author.name print(name)
正向查詢(按字段:authors):
# 眉全部做者的名字以及手機號 book_obj=Book.objects.filter(title="眉").first() authors=book_obj.authors.all() for author_obj in authors: print(author_obj.name,author_obj.authorDetail.telephone)
反向查詢(按表名:book_set):
# 查詢egon出過的全部書籍的名字 author_obj=Author.objects.get(name="egon") book_list=author_obj.book_set.all() #與egon做者相關的全部書籍 for book_obj in book_list: print(book_obj.title)
# 正向查詢----查詢紅樓夢全部做者名稱 book=Book.objects.filter(name='紅樓夢').first() ret=book.authors.all() print(ret) for auth in ret: print(auth.name) # 反向查詢 查詢lqz這個做者寫的全部書 author=Author.objects.filter(name='lqz').first() ret=author.book_set.all() print(ret)
注意:
你能夠經過在 ForeignKey() 和ManyToManyField的定義中設置 related_name 的值來覆寫 FOO_set 的名稱。例如,若是 Article model 中作一下更改:
publish = ForeignKey(Book, related_name='bookList')
那麼接下來就會如咱們看到這般:
# 查詢 人民出版社出版過的全部書籍 publish=Publish.objects.get(name="人民出版社") book_list=publish.bookList.all() # 與人民出版社關聯的全部書籍對象集合
Django 還提供了一種直觀而高效的方式在查詢(lookups)中表示關聯關係,它能自動確認 SQL JOIN 聯繫。要作跨關係查詢,就使用兩個下劃線來連接模型(model)間關聯字段的名稱,直到最終連接到你想要的model 爲止。
''' 正向查詢按字段,反向查詢按表名小寫用來告訴ORM引擎join哪張表 '''
# 練習: 查詢蘋果出版社出版過的全部書籍的名字與價格(一對多) # 正向查詢 按字段:publish queryResult=Book.objects.filter(publish__name="蘋果出版社").values_list("title","price") # 反向查詢 按表名:book queryResult=Publish.objects.filter(name="蘋果出版社").values_list("book__title","book__price")查詢的本質同樣,就是select from的表不同
# 正向查詢按字段,反向查詢按表名小寫 # 查詢紅樓夢這本書出版社的名字 # select * from app01_book inner join app01_publish # on app01_book.publish_id=app01_publish.nid ret=Book.objects.filter(name='紅樓夢').values('publish__name') print(ret) ret=Publish.objects.filter(book__name='紅樓夢').values('name') print(ret)
# 練習: 查詢alex出過的全部書籍的名字(多對多) # 正向查詢 按字段:authors: queryResult=Book.objects.filter(authors__name="yuan").values_list("title") # 反向查詢 按表名:book queryResult=Author.objects.filter(name="yuan").values_list("book__title","book__price")
# 正向查詢按字段,反向查詢按表名小寫 # 查詢紅樓夢這本書出版社的名字 # select * from app01_book inner join app01_publish # on app01_book.publish_id=app01_publish.nid ret=Book.objects.filter(name='紅樓夢').values('publish__name') print(ret) ret=Publish.objects.filter(book__name='紅樓夢').values('name') print(ret) # sql 語句就是from的表不同 # -------多對多正向查詢 # 查詢紅樓夢全部的做者 ret=Book.objects.filter(name='紅樓夢').values('authors__name') print(ret) # ---多對多反向查詢 ret=Author.objects.filter(book__name='紅樓夢').values('name') ret=Author.objects.filter(book__name='紅樓夢').values('name','author_detail__addr') print(ret)
# 查詢alex的手機號 # 正向查詢 ret=Author.objects.filter(name="alex").values("authordetail__telephone") # 反向查詢 ret=AuthorDetail.objects.filter(author__name="alex").values("telephone")
# 查詢lqz的手機號 # 正向查 ret=Author.objects.filter(name='lqz').values('author_detail__telephone') print(ret) # 反向查 ret= AuthorDatail.objects.filter(author__name='lqz').values('telephone') print(ret)
# 練習: 查詢人民出版社出版過的全部書籍的名字以及做者的姓名 # 正向查詢 queryResult=Book.objects.filter(publish__name="人民出版社")values_list("title","authors__name") # 反向查詢 queryResult=Publish.objects.filter(name="人民出版社").values_list("book__title","book__authors__age","book__authors__name") # 練習: 手機號以151開頭的做者出版過的全部書籍名稱以及出版社名稱 # 方式1: queryResult=Book.objects.filter(authors__authorDetail__telephone__regex="151") .values_list("title","publish__name") # 方式2: ret=Author.objects.filter(authordetail__telephone__startswith="151").values("book__title","book__publish__name")
# ----進階練習,連續跨表 # 查詢手機號以33開頭的做者出版過的書籍名稱以及書籍出版社名稱 # author_datail author book publish # 基於authorDatail表 ret=AuthorDatail.objects.filter(telephone__startswith='33').values('author__book__name','author__book__publish__name') print(ret) # 基於Author表 ret=Author.objects.filter(author_detail__telephone__startswith=33).values('book__name','book__publish__name') print(ret) # 基於Book表 ret=Book.objects.filter(authors__author_detail__telephone__startswith='33').values('name','publish__name') print(ret) # 基於Publish表 ret=Publish.objects.filter(book__authors__author_detail__telephone__startswith='33').values('book__name','name') print(ret)
publish = ForeignKey(Blog, related_name='bookList')
# 練習: 查詢人民出版社出版過的全部書籍的名字與價格(一對多) # 反向查詢 再也不按表名:book,而是related_name:bookList queryResult=Publish.objects .filter(name="人民出版社") .values_list("bookList__title","bookList__price")
反向查詢時,若是定義了related_name ,則用related_name替換表名,例如: