最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

介紹Python的Django框架中的QuerySets

 更新時(shí)間:2015年04月20日 10:33:58   投稿:goldensun  
這篇文章主要介紹了Python的Django框架中的QuerySets,QuerySet是Django中的一個(gè)內(nèi)置對象列表,經(jīng)常被用于數(shù)據(jù)庫操作,需要的朋友可以參考下

 Django的QuerySets酷斃了!

在本文中我將解釋一下QuerySets是什么,它是如何工作的(如果你對它已經(jīng)熟悉了,你可以直接跳到第二部分),我認(rèn)為如果可以的話你應(yīng)該總是返回QuerySets對象,下面讓我來談?wù)勅绾巫觥?br /> QuerySets很酷

QuerySet,本質(zhì)上是一個(gè)給定的模型的對象列表。我說“列表”而不是“組”或更正式的“集合”因?yàn)樗怯行虻?。事?shí)上,你可能已經(jīng)熟悉如何獲得QuerySets,因?yàn)檫@就是你調(diào)用variousBook.objects.XXX()方法后得到的對象。例如,考慮下面的語句:
 

Book.objects.all()

all()返回的就是Book實(shí)例的一個(gè)QuerySet,它正好包括allBookinstances,下面的其他調(diào)用你可能已經(jīng)知道:
 

# Return all books published since 1990
Book.objects.filter(year_published__gt=1990)
 
# Return all books *not* written by Richard Dawkins
Book.objects.exclude(author='Richard Dawkins')
 
# Return all books, ordered by author name, then
# chronologically, with the newer ones first.
Book.objects.order_by('author', '-year_published')

關(guān)于 QuerySet s最酷的是,由于這些函數(shù)操作、返回的都是一個(gè)QuerySet,你可以把他們鏈起來:
 

# Return all book published after 1990, except for
# ones written by Richard Dawkins. Order them by
# author name, then chronologically, with the newer
# ones first.
Book.objects.filter(year_published__gt=1990) \
      .exclude(author='Richard Dawkins') \
      .order_by('author', '-year_published')

而且這并不是全部的,它更快!

    在內(nèi)部,一個(gè)QuerySet可以被構(gòu)造、過濾、切片及像普通變量那樣在沒有實(shí)際數(shù)據(jù)庫查詢的情況下隨便傳遞,在評估處理完QuerySet前不產(chǎn)生數(shù)據(jù)庫活動。

所有我們確認(rèn)了QuerySets很酷,不是么?

盡可能的返回QuerySets

我最近曾在一個(gè)Django應(yīng)用中用一個(gè)模型來表示樹(數(shù)據(jù)結(jié)構(gòu),不是圣誕裝飾)。這意味著每一個(gè)實(shí)例在樹上都有一個(gè)指向它父節(jié)點(diǎn)的鏈接。它看起來像這樣:
 

class Node(models.Model):
  parent = models.ForeignKey(to='self', null=True, blank=True)
  value = models.IntegerField()
   
  def __unicode__(self):
    return 'Node #{}'.format(self.id)
   
  def get_ancestors(self):
    if self.parent is None:
      return []
    return [self.parent] + self.parent.get_ancestors()

這工作的相當(dāng)好。麻煩的是,我不得不添加另一種方法,get_larger_ancestors,它應(yīng)該返回所有值大于當(dāng)前節(jié)點(diǎn)的的父節(jié)點(diǎn)。這是我能實(shí)現(xiàn)這個(gè):
 

def get_larger_ancestors(self):
    ancestors = self.get_ancestors()
    return [node for node in ancestors if node.value > self.value]

問題是,我基本上會在名單上審查兩次——Django一次,我自己一次。這讓我考慮到-如果get_ancestors返回QuerySet而不是列表會怎樣呢?我可以這樣做:
 

def get_larger_ancestors(self):
    return self.get_ancestors().filter(value__gt=self.value)

很簡單,這里更重要的是我沒有遍歷對象。我可以對get_larger_ancestors的返回使用任何我想使用的過濾器,而且感到安全——我不會得到一個(gè)未知大小的對象列表。這樣的主要優(yōu)勢是我一直使用相同的查詢接口。當(dāng)用戶得到了一大堆的對象,我們不知道他想怎樣對它們進(jìn)行切片分塊。而返回QuerySet對象時(shí)我保證用戶知道如何處理它。


但如何實(shí)現(xiàn)get_ancestorsto返回一個(gè)QuerySet呢?這是一個(gè)小技巧。用一條簡單的查詢收集我們需要的數(shù)據(jù)是不可能的,使用任何預(yù)定數(shù)量的查詢也是不可能的。我們要找的法則是動態(tài)的,選擇的實(shí)現(xiàn)看起來很像它現(xiàn)在的樣子,下面就是選擇,一個(gè)更好的實(shí)現(xiàn):
 

class Node(models.Model):
  parent = models.ForeignKey(to='self', null=True, blank=True)
  value = models.IntegerField()
   
  def __unicode__(self):
    return 'Node #{}'.format(self.id)
   
  def get_ancestors(self):
    if self.parent is None:
      return Node.objects.none()
    return Node.objects.filter(pk=self.parent.pk) | self.parent.get_ancestors()
   
  def get_larger_ancestors(self):
    return self.get_ancestors().filter(value__gt=self.value)

稍停一會,沉淀一下,馬上說出細(xì)節(jié)。

我想說的是,不論什么時(shí)候你返回一系列對象——你應(yīng)該總是返回一個(gè)QuerySet替代。這樣做將允許用戶使用一種簡單、熟悉、具備更好性能的方法自由過濾、剪接和排序結(jié)果。

(從一個(gè)側(cè)面說get_ancestors查詢了數(shù)據(jù)庫,因?yàn)槲沂褂昧诉f歸的self.parent。這里有一個(gè)額外的數(shù)據(jù)庫執(zhí)行——當(dāng)實(shí)際檢測結(jié)果時(shí)執(zhí)行了這個(gè)函數(shù),未來又執(zhí)行了另外一次。當(dāng)我們在數(shù)據(jù)庫查詢上使用更多的過濾器或進(jìn)行高耗內(nèi)存的操作時(shí)我們得到了性能的提升。這里的例子

常見的QuerySet操作

所以,執(zhí)行簡單查詢時(shí)返回一個(gè)QuerySet很簡單。當(dāng)我們想實(shí)現(xiàn)復(fù)雜一點(diǎn)的東西,我們需要執(zhí)行相關(guān)操作(也包括一些助手函數(shù))。下面是些小竅門(作為練習(xí),試著理解我get_larger_ancestors的實(shí)現(xiàn))。

  •     聯(lián)合 - QuerySet的聯(lián)合運(yùn)算符是|,處理復(fù)制時(shí)管道“symbol.qs1 | qs2”返回所有來自qs1和qs2項(xiàng)目的QuerySet(都在QuerySet的項(xiàng)目將只在結(jié)果中出現(xiàn)一次)。
  •     交集 - 交集沒有特殊的操作,因?yàn)槟阋呀?jīng)知道怎么去做。 像filter等鏈接函數(shù)在原始的QuerySet和新過濾器之前起了交集的作用。
  •     差分 - 差分(數(shù)學(xué)上寫為qs1 \ qs2)代表所有在qs1而不在qs2中的項(xiàng)目。請注意,此操作是不對稱的(相對于以前的操作)。Python中恐怕沒有內(nèi)置的方式,但你可以這樣做:qs1.exclude(pk__in=qs2)
  •     從空開始 - 開起來沒有用處但實(shí)際并非如此,正如上面例子所展示的。很多時(shí)候,當(dāng)我們動態(tài)建立一個(gè)QuerySet聯(lián)合時(shí),我們需要從一個(gè)空列表開始,這是獲取它的方法:MyModel.objects.none().

相關(guān)文章

  • Python腳本實(shí)現(xiàn)自動刪除C盤臨時(shí)文件夾

    Python腳本實(shí)現(xiàn)自動刪除C盤臨時(shí)文件夾

    在日常使用電腦的過程中,臨時(shí)文件夾往往會積累大量的無用數(shù)據(jù),占用寶貴的磁盤空間,下面我們就來看看Python如何通過腳本實(shí)現(xiàn)自動刪除C盤臨時(shí)文件夾吧
    2025-01-01
  • Python實(shí)戰(zhàn)之實(shí)現(xiàn)獲取動態(tài)圖表

    Python實(shí)戰(zhàn)之實(shí)現(xiàn)獲取動態(tài)圖表

    這篇文章主要介紹了利用Python實(shí)現(xiàn)動態(tài)化圖表,文中的示例代碼介紹詳細(xì),對我們的工作或?qū)W習(xí)有一定的價(jià)值,感興趣的同學(xué)可以學(xué)習(xí)一下
    2021-12-12
  • python自動保存百度盤資源到百度盤中的實(shí)例代碼

    python自動保存百度盤資源到百度盤中的實(shí)例代碼

    這篇文章主要介紹了python自動保存百度盤資源到百度盤中的實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2019-08-08
  • Python正則表達(dá)式re.compile()和re.findall()詳解

    Python正則表達(dá)式re.compile()和re.findall()詳解

    re?模塊提供了不少有用的函數(shù),用以匹配字符串,下面這篇文章主要給大家介紹了關(guān)于Python正則表達(dá)式re.compile()和re.findall()的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • Python 同級目錄(兄弟目錄)調(diào)用方式

    Python 同級目錄(兄弟目錄)調(diào)用方式

    這篇文章主要介紹了Python 同級目錄(兄弟目錄)調(diào)用方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-02-02
  • Python變量作用域LEGB用法解析

    Python變量作用域LEGB用法解析

    這篇文章主要介紹了Python變量作用域LEGB用法解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-02-02
  • Python進(jìn)階之利用+和*進(jìn)行列表拼接

    Python進(jìn)階之利用+和*進(jìn)行列表拼接

    在我們學(xué)習(xí)python的過程中,有一個(gè)非常常見的語法,那就是利用+和*進(jìn)行序列的拼接以及其他操作。今天就帶大家從使用+和*進(jìn)行拼接出發(fā)認(rèn)識一個(gè)大家非常容易犯的代碼錯(cuò)誤。話不多說我們開始吧
    2023-04-04
  • 解決python2.7 查詢mysql時(shí)出現(xiàn)中文亂碼

    解決python2.7 查詢mysql時(shí)出現(xiàn)中文亂碼

    這篇文章主要介紹了python操作mysql中文顯示亂碼的解決方法,是Python數(shù)據(jù)庫程序設(shè)計(jì)中經(jīng)常會遇到的問題,非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2016-10-10
  • Python注釋、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、偽“選擇結(jié)構(gòu)”用法實(shí)例分析

    Python注釋、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、偽“選擇結(jié)構(gòu)”用法實(shí)例分析

    這篇文章主要介紹了Python注釋、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、偽“選擇結(jié)構(gòu)”用法,結(jié)合實(shí)例形式分析了Python注釋、分支結(jié)構(gòu)、循環(huán)結(jié)構(gòu)、偽“選擇結(jié)構(gòu)”相關(guān)功能、用法及操作注意事項(xiàng),需要的朋友可以參考下
    2020-01-01
  • pandas中DataFrame重置索引的幾種方法

    pandas中DataFrame重置索引的幾種方法

    在pandas中,經(jīng)常對數(shù)據(jù)進(jìn)行處理 而導(dǎo)致數(shù)據(jù)索引順序混亂,從而影響數(shù)據(jù)讀取、插入等,所以小編總結(jié)了幾種索引重置的方法,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05

最新評論

苏州市| 大安市| 巴林右旗| 桂林市| 乌拉特前旗| 黄平县| 辰溪县| 九寨沟县| 乌鲁木齐县| 海安县| 靖江市| 比如县| 和硕县| 利川市| 大兴区| 开江县| 涪陵区| 关岭| 阜宁县| 龙胜| 东海县| 景宁| 岚皋县| 瑞安市| 盱眙县| 鄂托克前旗| 梁山县| 沽源县| 巴彦淖尔市| 藁城市| 洛阳市| 南雄市| 田东县| 建瓯市| 大渡口区| 淮滨县| 宝鸡市| 广昌县| 原平市| 金沙县| 西盟|