国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

DjangoModel數據訪問Makingqueries

2019-11-14 17:39:38
字體:
來源:轉載
供稿:網友

創建完Model之后, Django 自動為你提供一套數據庫抽象層的API,利用它可以完成創建,提取,更新,刪除對象的操作。

以下面的Model為例:

class Blog(models.Model):    name = models.CharField(max_length=100)    tagline = models.TextField()    # On Python 3: def __str__(self):    def __unicode__(self):        return self.nameclass Author(models.Model):    name = models.CharField(max_length=50)    email = models.EmailField()    # On Python 3: def __str__(self):    def __unicode__(self):        return self.nameclass Entry(models.Model):    blog = models.ForeignKey(Blog)    headline = models.CharField(max_length=255)    body_text = models.TextField()    pub_date = models.DateField()    mod_date = models.DateField()    authors = models.ManyToManyField(Author)    n_comments = models.IntegerField()    n_pingbacks = models.IntegerField()    rating = models.IntegerField()    # On Python 3: def __str__(self):    def __unicode__(self):        return self.headline

創建Creating objects

>>> b = Blog(name='Beatles Blog', tagline='All the latest Beatles news.')>>> b.save()

Django 用一種很直觀的表達方式將Python對象和數據表對應起來:一個model類對應一張數據表,一個model實例對應表中的某一行記錄。

以創建對象為例:只要將關鍵字參數傳遞給model類,然后調用save()保存到數據庫即可

這段代碼就會在幕后執行一條INSERT SQL語句。除非你顯式地調用save()方法,否則Django不會保存到數據庫中。

你可以使用create()方法一次完成新建并保存對象的操作。

修改Saving changes to objects

>> b5.name = 'New name'>> b5.save()

Saving ForeignKey and ManyToManyField fields

更新ForeignKey字段和保存普通字段沒什么差別;只是在給字段分配對象時要注意對象類型一定要正確:

>>> entry = Entry.objects.get(pk=1)>>> cheese_blog = Blog.objects.get(name="Cheddar Talk")>>> entry.blog = cheese_blog>>> entry.save()

更新ManyToManyField就有些不同;要在字段上使用add()方法來添加關系:

>>> joe = Author.objects.create(name="Joe")>>> entry.authors.add(joe)

一次添加多個:

>>> john = Author.objects.create(name="John")>>> paul = Author.objects.create(name="Paul")>>> george = Author.objects.create(name="George")>>> ringo = Author.objects.create(name="Ringo")>>> entry.authors.add(john, paul, george, ringo)

檢索對象 (Retrieving objects)

要檢索數據庫中的對象,就要為你的model 類構造一個查詢集QuerySet。一個QuerySet就代表數據庫中的一組數據。它可以有一個或很多個,也可以通過filter根據給定的參數對數據集做進一步篩選。在SQL術語中,QuerySet相當于SELECT語句,filter相當于WHERE或LIMIT這樣的限定從句。

檢索所有的對象

all_entries = Entry.objects.all()

使用過濾器filter檢索特定的對象

filter(**kwargs)

    返回滿足篩選條件的新QuerySet

exclude(**kwargs)

    返回不滿足篩選條件的新QuerySet

Entry.objects.filter(pub_date__year=2006)

鏈式過濾:

>>> Entry.objects.filter(...     headline__startswith='What'... ).exclude(...     pub_date__gte=datetime.date.today()... ).filter(...     pub_date__gte=datetime(2005, 1, 30)... )

查詢一個單獨的對象

>>> one_entry = Entry.objects.get(pk=1)

注意當使用get查詢時若對象不存在會產生DoesNotExist異常。

QuerySet是惰性的

QuerySets是惰性的。創建 QuerySet 的動作不涉及任何數據庫操作。你可以一直添加過濾器,在這個過程中,Django不會執行任何數據庫查詢,除非QuerySet被執行。

切片

可以用python的數組切片語法來限制你的QuerySet以得到一部分結果。它等價于SQL中的LIMIT和OFFSET。

例如,下面的這個例子返回前五個對象:

>>> Entry.objects.all()[:5]

Django 不支持對查詢集做負數索引。

跨關系查詢

Django 提供了一種直觀而高效的方式在查詢(lookups)中表示關聯關系,它能自動確認 SQL JOIN 聯系。要做跨關系查詢,就使用雙下劃線來鏈接模型(model)間關聯字段的名稱,直到最終鏈接到你想要的 model 為止。

Blog.objects.filter(entry__authors__name='Lennon')

要注意的是如果跨關系對象有多個符合條件,被查詢對象會返回多次:

Blog.objects.filter(entry__headline='note')

上面如果有個Blog鏈接多個headline為note的Entry對象,此Blog會返回多次。

跨一對多/多對多關系

對于包含在同一個filter()中的篩選條件,查詢集要同時滿足所有篩選條件。而對于連續的filter(),查詢集的范圍是依次限定的。但對于跨一對多/多對多關系查詢來說,在第二種情況下,篩選條件針對的是主model所有的關聯對象,而不是被前面的filter()過濾后的關聯對象。

這聽起來會讓人迷糊,舉個例子會講得更清楚。要檢索這樣的 blog:它要關系一個大標題中含有 "Lennon" 并且在2008年出版的entry(這個entry同時滿足這兩個條件),可以這樣寫:

Blog.objects.filter(entry__headline__contains='Lennon',        entry__pub_date__year=2008)

要檢索另外一種 blog:它關聯一個大標題含有"Lennon"的 entry ,又關聯一個在2008年出版的 entry (一個entry的大標題含有Lennon,同一個或另一個entry是在2008年出版的)。可以這樣寫:

Blog.objects.filter(entry__headline__contains='Lennon').filter(        entry__pub_date__year=2008)

上述原則同樣適用于exclude():一個單獨exclude()中的所有篩選條件都是作用于同一個實例 (如果這些條件都是針對同一個一對多/多對多的關系)。連續的filter()或exclude()卻根據同樣的篩選條件,作用于不同的關聯對象。

Filters can reference fields on the model

class F

在上面所有的例子中,我們構造的過濾器都只是將字段值與某個常量做比較。如果我們要對兩個字段的值做比較,那該怎么做呢?

Django 提供F()來做這樣的比較。F()的實例可以在查詢中引用字段,來比較同一個model實例中兩個不同字段的值。

例如:要查詢回復數(comments)大于廣播數(pingbacks)的博文(blog entries),可以構造一個 F() 對象在查詢中引用評論數量:

>>> from django.db.models import F>>> Entry.objects.filter(n_comments__gt=F('n_pingbacks'))

Django 支持 F() 對象之間以及 F() 對象和常數之間的加減乘除和取模的操作。例如,要找到廣播數等于評論數兩倍的博文,可以這樣修改查詢語句:

>>> Entry.objects.filter(n_comments__gt=F('n_pingbacks') * 2)

要查找閱讀數量小于評論數與廣播數之和的博文,查詢如下:

>>> Entry.objects.filter(rating__lt=F('n_comments') + F('n_pingbacks'))

你也可以在 F() 對象中使用雙下劃線做跨關系查詢。F() 對象使用雙下劃線引入必要的關聯對象。例如,要查詢博客(blog)名稱與作者(author)名稱相同的博文(entry),查詢就可以這樣寫:

>>> Entry.objects.filter(authors__name=F('blog__name'))

對于Date和datetime域,可以加減timedelta對象。

返回出版3天以后修改的博文:

>>> from datetime import timedelta>>> Entry.objects.filter(mod_date__gt=F('pub_date') + timedelta(days=3))

F對象現在也支持位運算(bitand(),bitor()):

>>> F('somefield').bitand(16)

主鍵查詢的簡捷方式 (The pk lookup shortcut)

為使用方便考慮,Django 用pk代表主鍵"PRimary key"。

以Blog為例, 主鍵是id字段,所以下面三個語句都是等價的:

>>> Blog.objects.get(id__exact=14) # Explicit form>>> Blog.objects.get(id=14) # __exact is implied>>> Blog.objects.get(pk=14) # pk implies id__exact

在LIKE語句中轉義百分號%和下劃線_ (Escaping percent signs and underscores in LIKE statements)

字段篩選條件相當于LIKE SQL語句 (iexactcontainsicontainsstartswithistartswithendswith 和 iendswith) ,它會自動轉義兩個特殊符號,百分號(%)和下劃線(_)。(在LIKE語句中,百分號%表示多字符匹配,而下劃線_表示單字符匹配。)

這就意味著我們可以直接使用這兩個字符,而不用考慮他們的SQL語義。例如,要查詢大標題中含有一個百分號%的entry:

>>> Entry.objects.filter(headline__contains='%')

Django會處理轉義,下劃線_和百分號%的處理方式相同,Django都會自動轉義。

緩存和查詢

每個QuerySet都包含一個緩存,以減少對數據庫的訪問。要編寫高效代碼,就要理解緩存是如何工作的。

一個QuerySet時剛剛創建的時候,緩存是空的。 QuerySet 第一次運行時,會執行數據庫查詢,接下Django就在QuerySet的緩存中保存查詢的結果,并根據請求返回這些結果(比如,后面再次調用這個 QuerySet 的時候)。再次運行 QuerySet 時就會重用這些緩存結果。

要牢住上面所說的緩存行為,否則在使用 QuerySet 時可能會給你造成不小的麻煩。例如,創建下面兩個 QuerySet ,并對它們求值,然后釋放:

>>> print([e.headline for e in Entry.objects.all()])>>> print([e.pub_date for e in Entry.objects.all()])

這就意味著相同的數據庫查詢將執行兩次,事實上讀取了兩次數據庫。而且,這兩次讀出來的列表可能并不完全相同,因為存在這種可能:在兩次讀取之間,某個 Entry 被添加到數據庫中,或是被刪除了。

要避免這個問題,只要簡單地保存QuerySet然后重用即可:

>>> queryset = Entry.objects.all()>>> print([p.headline for p in queryset]) # 對查詢集求值.>>> print([p.pub_date for p in queryset]) # 使用緩存.

When querysets are not cached

查詢集并不總是緩存結果,當查詢集執行部分查詢時,會先檢查緩存,如果它沒有被填充,部分查詢返回的結果不會被緩存。這意味著,使用切片查詢不會填充緩存。

例如,重復的切片查詢每次都會訪問數據庫:

>>> queryset = Entry.objects.all()>>> print queryset[5] # 訪問數據庫>>> print queryset[5] # 再次訪問數據庫

但是,如果整個查詢集已經被求值,切片查詢會使用緩存:

>>> queryset = Entry.objects.all()>>> [entry for entry in queryset] # 查詢數據庫>>> print queryset[5] # 使用緩存>>> print queryset[5] # 使用緩存

下面是一些會填充緩存的操作:

>>> [entry for entry in queryset]>>> bool(queryset)>>> entry in queryset>>> list(queryset) 

用Q對象實現復雜查找 (Complex lookups with Q objects)

在filter() 等函式中關鍵字參數彼此之間都是 "AND" 關系。如果你要執行更復雜的查詢(比如,實現篩選條件的OR關系),可以使用Q對象。

Q對象(django.db.models.Q)是用來封裝一組查詢關鍵字的對象。

例如,下面這個Q對象封裝了一個單獨的 LIKE 查詢:

from django.db.models import QQ(question__startswith='What')

Q 對象可以用 & 和 | 運算符進行連接。當某個操作連接兩個 Q 對象時,就會產生一個新的等價的 Q 對象。

例如,下面這段語句就產生了一個Q,這是用 "OR" 關系連接的兩個"question__startswith" 查詢:

Q(question__startswith='Who') | Q(question__startswith='What')

上面的例子等價于下面的 SQL WHERE 從句:

WHERE question LIKE 'Who%' OR question LIKE 'What%'

你可以用 & 和 | 連接任意多的Q對象,而且可以用括號分組。Q 對象也可以用 ~ 操作取反,而且普通查詢和取反查詢(NOT)可以連接在一起使用:

Q(question__startswith='Who') | ~Q(pub_date__year=2005)

每種查詢函式(比如 filter(), exclude(), get()) 除了能接收關鍵字參數以外,也能以位置參數的形式接受一個或多個 Q 對象。如果你給查詢函式傳遞了多個 Q 對象,那么它們彼此間都是 "AND" 關系。例如:

Poll.objects.get(    Q(question__startswith='Who'),    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

... 大體可以翻譯為下面的 SQL:

SELECT * from polls WHERE question LIKE 'Who%'    AND (pub_date = '2005-05-02' OR pub_date = '2005-05-06')

查找函式可以混用 Q 對象和關鍵字參數。查詢函式的所有參數(Q 關系和關鍵字參數) 都是 "AND" 關系。但是,如果參數中有 Q 對象,它必須排在所有的關鍵字參數之前。例如:

Poll.objects.get(    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)),    question__startswith='Who')

是一個有效的查詢。但下面這個查詢雖然看上去和前者等價:

# 無效查詢Poll.objects.get(    question__startswith='Who',    Q(pub_date=date(2005, 5, 2)) | Q(pub_date=date(2005, 5, 6)))

但這個查詢卻是無效的。

對象比較 (Comparing objects)

要比較兩個對象,就和Python 一樣,使用雙等號運算符:==。實際上比較的是兩個model的主鍵值。

以上面的Entry為例,下面兩個語句是等價的:

>>> some_entry == other_entry>>> some_entry.id == other_entry.id

如果model的主鍵名稱不是id,也沒關系。Django會自動比較主鍵的值,而不管他們的名稱是什么。例如,如果一個model的主鍵字段名稱是name,那么下面兩個語句是等價的:

>>> some_obj == other_obj>>> some_obj.name == other_obj.name

對象刪除(Deleting objects)

刪除方法就是delete()。它運行時立即刪除對象而不返回任何值。例如:

e.delete()

你也可以一次性刪除多個對象。每個QuerySet 都有一個delete() 方法,它一次性刪除 QuerySet 中所有的對象。

例如,下面的代碼將刪除 pub_date 是2005年的 Entry 對象:

Entry.objects.filter(pub_date__year=2005).delete()

要牢記這一點:無論在什么情況下,QuerySet 中的 delete() 方法都只使用一條 SQL 語句一次性刪除所有對象,而并不是分別刪除每個對象。如果你想使用在model中自定義的delete() 方法,就要自行調用每個對象的delete方法。(例如,遍歷 QuerySet,在每個對象上調用 delete()方法),而不是使用QuerySe 中的 delete()方法。

在Django刪除對象時,會模仿SQL約束ON DELETE CASCADE的行為,換句話說,刪除一個對象時也會刪除與它相關聯的外鍵對象。例如:

b = Blog.objects.get(pk=1)# This will delete the Blog and all of its Entry objects.b.delete()

要注意的是: delete() 方法是QuerySet上的方法,但并不適用于 Manager 本身。這是一種保護機制,是為了避免意外地調用Entry.objects.delete() 方法導致 所有的 記錄被誤刪除。如果你確認要刪除所有的對象,那么你必須顯式地調用:

Entry.objects.all().delete()

復制Copying model instances

復制對象并沒有內置的函數,最簡單的情況,將pk設為None。

blog = Blog(name='My blog', tagline='Blogging is easy')blog.save() # blog.pk == 1blog.pk = Noneblog.save() # blog.pk == 2

如果使用繼承的話,情況會復雜一點:

class ThemeBlog(Blog):    theme = models.CharField(max_length=200)django_blog = ThemeBlog(name='Django', tagline='Django is easy', theme='python')django_blog.save() # django_blog.pk == 3

需要將pk和id都設為None:

django_blog.pk = Nonedjango_blog.id = Nonedjango_blog.save() # django_blog.pk == 4

這樣寫是不會復制關系對象的,要復制關系對象,還需要一點代碼:

entry = Entry.objects.all()[0] # some previous entryold_authors = entry.authors.all()entry.pk = Noneentry.save()entry.authors = old_authors # saves new many2many relations

一次更新多個對象 (Updating multiple objects at once)

有時你想對QuerySet中的所有對象,一次更新某個字段的值。這個要求可以用 update() 方法完成。例如:

# Update all the headlines with pub_date in 2007.Entry.objects.filter(pub_date__year=2007).update(headline='Everything is the same')

這種方法僅適用于非關系字段和ForeignKey外鍵字段。更新非關系字段時,傳入的值應該是一個常量。更新ForeignKey字段時,傳入的值應該是你想關聯的那個類的某個實例。例如:

>>> b = Blog.objects.get(pk=1)# Change every Entry so that it belongs to this Blog.>>> Entry.objects.all().update(blog=b)

 update() 方法也是即時生效,返回與查詢匹配的行數(可能不等于被更新的行數,因為有些行已經是新值,不需要被更新)。 在QuerySet進行更新時,唯一的限制就是一次只能更新一個數據表,就是當前 model 的主表。你可以嘗試更新關聯表和與此類似的操作,但是只有主表的條目被更新:

>>> b = Blog.objects.get(pk=1)# Update all the headlines belonging to this Blog.>>> Entry.objects.select_related().filter(blog=b).update(headline='Everything is the same')

要小心的是:update() 方法是直接翻譯成一條SQL語句的。因此它是直接地一次完成所有更新。它不會調用你的 model 中的save() 方法,也不會發出pre_save 和post_save信號(這些信號在調用 save() 方法時產生)。如果你想保存QuerySet中的每個對象,并且調用每個對象各自的save() 方法,那么你不必另外多寫一個函式。只要遍歷這些對象,依次調用 save() 方法即可:

for item in my_queryset:    item.save()

在調用update時可以使用 F() 對象來把某個字段的值更新為另一個字段的值。這對于自增記數器是非常有用的。例如,給所有的博文 (entry) 的廣播數 (pingback) 加一:

>>> Entry.objects.all().update(n_pingbacks=F('n_pingbacks') + 1)

但是,與 F() 對象在查詢時所不同的是,在filter 和 exclude子句中,你不能在 F() 對象中引入關聯關系(NO-Join),你只能引用當前 model 中要更新的字段。如果你在 F() 對象引入了Join 關系object,就會拋出 FieldError 異常:

# THIS WILL RAISE A FieldError>>> Entry.objects.update(headline=F('blog__name'))

對象關聯(Related objects)

當你定義在 model 定義關系時 (例如,ForeignKey, OneToOneField, 或 ManyToManyField),model 的實例自帶一套很方便的API以獲取關聯的對象。

以最上面的 models 為例,一個 Entry 對象e能通過blog屬性獲得相關聯的Blog對象:e.blog。

Django也提供反向獲取關聯對象的API,就是由從被關聯的對象得到其定義關系的主對象。例如,一個Blog類的實例b對象通過entry_set屬性得到所有相關聯的Entry對象列表: 

b.entry_set.all()

一對多關系(One-to-many relationships)

正向(Forward)

如果一個model有一個ForeignKey字段,我們只要通過使用關聯model的名稱就可以得到相關聯的外鍵對象。

>>> e = Entry.objects.get(id=2)>>> e.blog # Returns the related Blog object.

你可以設置和獲得外鍵屬性。正如你所期望的,改變外鍵的行為并不引發數據庫操作,直到你調用 save()方法時,才會保存到數據庫。例如:

>>> e = Entry.objects.get(id=2)>>> e.blog = some_blog>>> e.save()

如果外鍵字段 ForeignKey 有一個 null=True 的設置(它允許外鍵接受空值 NULL),你可以賦給它空值 None 。例如:

>>> e = Entry.objects.get(id=2)>>> e.blog = None>>> e.save() # "UPDATE blog_entry SET blog_id = NULL ..

在一對多關系中,第一次正向獲取關聯對象時,關聯對象會被緩存。其后根據外鍵訪問時這個實例,就會從緩存中獲得它。例如:

>>> e = Entry.objects.get(id=2)>>> print(e.blog)  # 訪問數據庫>>> print(e.blog)  # 使用緩存

要注意的是,QuerySet 的select_related() 方法提前將所有的一對多關系放入緩存中。例如:

>>> e = Entry.objects.select_related().get(id=2)>>> print(e.blog)  # 使用緩存>>> print(e.blog)  # 使用緩存

逆向關聯(Following relationships "backward")

如果model有一個ForeignKey外鍵字段,那么外聯model的實例可以通過訪問Manager來得到所有相關聯的源model的實例。默認情況下,這個Manager被命名為 FOO_set, 這里面的 FOO 就是源 model 的小寫名稱。這個Manager返回QuerySets,它是可過濾和可操作的,在上面 "對象獲取(Retrieving objects)" 有提及。

>>> b = Blog.objects.get(id=1)>>> b.entry_set.all() # Returns all Entry objects related to Blog.# b.entry_set is a Manager that returns QuerySets.>>> b.entry_set.filter(headline__contains='Lennon')>>> b.entry_set.count()

 你可以通過在ForeignKey() 的定義中設置related_name的值來覆寫FOO_set 的名稱。例如,如果 Entry model 中做一下更改: blog = ForeignKey(Blog, related_name='entries'),那么接下來就會如我們看到這般:

>>> b = Blog.objects.get(id=1)>>> b.entries.all() # Returns all Entry objects related to Blog.# b.entries is a Manager that returns QuerySets.>>> b.entries.filter(headline__contains='Lennon')>>> b.entries.count()

 ForeignKey Manager 還有如下一些方法。下面僅僅對它們做一個簡短介紹:

add(obj1, obj2, ...)

將某個特定的 model 對象添加到被關聯對象集合中。

create(**kwargs)

創建并保存一個新對象,然后將這個對象加被關聯對象的集合中,然后返回這個新對象。

remove(obj1, obj2, ...)

將某個特定的對象從被關聯對象集合中去除。

clear()

清空被關聯對象集合。

想一次指定關聯集合的成員,那么只要給關聯集合分配一個可迭代的對象即可。它可以包含對象的實例,也可以只包含主鍵的值。例如:

b = Blog.objects.get(id=1)b.entry_set = [e1, e2]

在這個例子中,e1 和 e2 可以是完整的 Entry 實例,也可以是整型的主鍵值。

如果 clear() 方法是可用的,在迭代器(上例中就是一個列表)中的對象加入到 entry_set 之前,已存在于關聯集合中的所有對象將被清空。如果 clear() 方法 不可用,原有的關聯集合中的對象就不受影響,繼續存在。

這一節提到的每一個 "reverse" 操作都是實時操作數據庫的,每一個添加,創建,刪除操作都會及時保存將結果保存到數據庫中。

多對多關系(Many-to-many relationships)

在多對多關系的任何一方都可以使用 API 訪問相關聯的另一方。多對多的 API 用起來和上面提到的 "逆向" 一對多關系關系非常相象。

唯一的差雖就在于屬性的命名: ManyToManyField 所在的 model (為了方便,我稱之為源model A) 使用字段本身的名稱來訪問關聯對象;而被關聯的另一方則使用 A 的小寫名稱加上 '_set' 后綴(這與逆向的一對多關系非常相象)。

下面這個例子會讓人更容易理解:

e = Entry.objects.get(id=3)e.authors.all() # Returns all Author objects for this Entry.e.authors.count()e.authors.filter(name__contains='John')a = Author.objects.get(id=5)a.entry_set.all() # Returns all Entry objects for this Author.

與 ForeignKey 一樣, ManyToManyField 也可以指定 related_name。在上面的例子中,如果 Entry 中的 ManyToManyField 指定 related_name='entries',那么接下來每個 Author 實例的 entry_set 屬性都被 entries 所代替。

一對一關系(One-to-one relationships)

相對于多對一關系而言,一對一關系是非常簡單的。如果你在 model 中定義了一個 OneToOneField 關系,那么你就可以用這個字段的名稱做為屬性來訪問其所關聯的對象。

class EntryDetail(models.Model):    entry = models.OneToOneField(Entry)    details = models.TextField()ed = EntryDetail.objects.get(id=2)ed.entry # Returns the related Entry object.

與 "reverse" 查詢不同的是,一對一關系的關聯對象也可以訪問Manager對象,但是這個Manager表現一個單獨的對象,而不是一個列表:

e = Entry.objects.get(id=2)e.entrydetail # returns the related EntryDetail object

如果一個空對象被賦予關聯關系,Django就會拋出一個DoesNotExist 異常。

和你定義正向關聯所用的方式一樣,類的實例也可以賦予逆向關聯關系:

e.entrydetail = ed

關系中的反向連接是如何做到的?

其他對象關系的映射(ORM)需要你在關聯雙方都定義關系。而 Django 的開發者則認為這違背了 DRY 原則 (Don't Repeat Yourself),所以Django只需要你在一方定義關系即可。

但僅由一個model類并不能知道其他model 類是如何與它關聯的,除非是其他model也被載入,那么這是如何辦到的?

答案就在于 INSTALLED_APPS 設置中。任何一個 model 在第一次調用時,Django 就會遍歷所有的 INSTALLED_APPS 的所有models,并且在內存中創建中必要的反向連接。本質上來說,INSTALLED_APPS 的作用之一就是確認 Django 完整的model范圍。

在關聯對象上的查詢(Queries over related objects)

包含關聯對象的查詢與包含普通字段值的查詢都遵循相同的規則。為某個查詢指定某個值的時候,你可以使用一個類實例,也可以使用對象的主鍵值。

例如,如果你有一個 Blog 對象 b ,它的 id=5, 下面三個查詢是一樣的:

Entry.objects.filter(blog=b) # Query using object instanceEntry.objects.filter(blog=b.id) # Query using id from instanceEntry.objects.filter(blog=5) # Query using id directly

直接使用SQL(Falling back to raw SQL)

如果你發現某個 SQL 查詢用 Django 的數據庫映射來處理會非常復雜的話,你可以使用直接寫 SQL 來完成。

建議的方式是在你的model自定義方法或是自定義model的manager方法來運行查詢。雖然Django不要求數據操作必須在model層中執行。但是把你的商業邏輯代碼放在一個地方,從代碼組織的角度來看,也是十分明智的。

最后,要注意的是,Django的數據操作層僅僅是訪問數據庫的一個接口。你可以用其他的工具,編程語言,數據庫框架來訪問數據庫。對你的數據庫而言,沒什么是非用 Django 不可的。


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 澄迈县| 屯留县| 中西区| 阿拉善右旗| 乡宁县| 彭州市| 沙雅县| 襄城县| 易门县| 大洼县| 永丰县| 池州市| 九龙县| 岚皋县| 正镶白旗| 许昌市| 和平县| 冷水江市| 颍上县| 青浦区| 绍兴市| 黄大仙区| 讷河市| 康乐县| 黄陵县| 开封市| 会宁县| 丰都县| 夏河县| 乳源| 娱乐| 定州市| 庄河市| 徐汇区| 阿拉善盟| 江安县| 集贤县| 屯昌县| 鄂温| 奉贤区| 台江县|