天天看點

django 資料庫API參考(下)改變對象建立對象删除對象比較對象其它執行個體方法

django 資料庫API參考(下)  

dates(field, kind, order='ASC')

每個管理器擁有一個 dates() 方法, 它傳回一個 datetime.datetime 對象的清單, 表示經過給定的過濾器(由 kind 參數定義)過濾後的所有可用的 dates .

field 是 model 子產品中的一個 DateField 或 DateTimeField 屬性名.

kind 是 "year", "month" 或 "day" 中的一個. 結果清單中的每個 datetime.datetime 對象被截短為給定的 type 形式.

  • "year" 傳回一個該字段的不重複的年的清單.
  • "month" 傳回一個該字段的不重複的年/月的清單.
  • "day" 傳回一個該字段的不重複的年/月/日的清單.

order 隻能是 "ASC" 或 "DESC", 預設值是 'ASC'. 它指定如何排序結果.

這裡有一個例子, 使用上面定義的 Poll model

>>> from datetime import datetime
>>> p1 = Poll(slug='whatsup', question="What's up?",
...      pub_date=datetime(2005, 2, 20), expire_date=datetime(2005, 3, 20))
>>> p1.save()
>>> p2 = Poll(slug='name', question="What's your name?",
...      pub_date=datetime(2005, 3, 20), expire_date=datetime(2005, 4, 20))
>>> p2.save()
>>> Poll.objects.dates('pub_date', 'year')
[datetime.datetime(2005, 1, 1)]
>>> Poll.objects.dates('pub_date', 'month')
[datetime.datetime(2005, 2, 1), datetime.datetime(2005, 3, 1)]
>>> Poll.objects.dates('pub_date', 'day')
[datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)]
>>> Poll.objects.dates('pub_date', 'day', order='DESC')
[datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)]
>>> Poll.objects.filter(question__contains='name').dates('pub_date', 'day')
[datetime.datetime(2005, 3, 20)]
      

select_related()

關系是資料庫的根本, select_related() 方法"追蹤" 所有的關系對象, 并将它們預先存放到一個簡單的緩存中.這樣當需要調用一個具有一對多關系的對象時就不必再次通路資料庫.要做到這一點, 隻需對一個結果集使用 select_related() 方法.這可能導緻(某些時候相當)大的(有可能是不必要的)查詢, 但這卻意味着後續的關系使用會快很多.(俺的建議:對一個頻繁變化的多使用者資料庫,不要使用該參數)

舉例來說, 上面的 Poll 和 Choice models 中, 如果你這樣做:

c = Choice.objects.select_related().get(id=5)
      

那麼後面的 c.poll() 将不用通路資料庫.

注意這個 select_related 方法會盡可能遠的追蹤外鍵. 如果你有下面的 models:

class Poll(models.Model):
     # ...

class Choice(models.Model):
     # ...
     poll = models.ForeignKey(Poll)

class SingleVote(meta.Model):
     # ...
     choice = models.ForeignKey(Choice)
      

那麼調用 SingleVotes.objects.select_related().get(id=4) 會緩存相關的 choice 和 相關的 poll:

>>> sv = SingleVotes.objects.select_related().get(id=4)
>>> c = sv.choice         # Doesn't hit the database.
>>> p = c.poll            # Doesn't hit the database.

>>> sv = SingleVotes.objects.get(id=4)
>>> c = sv.choice         # Hits the database.
>>> p = c.poll            # Hits the database.
      

extra(params, select, where, tables)

有時候, Django 提供的查詢文法不太夠用. 為了滿足這些邊緣需求, Django 提供了 extra() 結果集修改器 - 一種提供額外查詢參數的機制.

要注意這些額外的方式對不同的資料庫引擎可能存在移植性問題.(因為你在顯式的書寫SQL語句),除非萬不得已,盡量避免這樣做:

params

下面描述的所有 額外-SQL 參數都必須是标準 Python 字元串格式(資料庫引擎會自動用引号将它引起).``params`` 參數可以包含任意多個的SQL參數.

select

select 關鍵字參數允許你選擇特定的字段. 它是一個字典(屬性名與 SQL 語句的映射). 舉例來說:

     Poll.objects.extra(
         select={
             'choice_count': 'SELECT COUNT(*) FROM choices WHERE poll_id = polls.id'
         }
     )

每個傳回的 ``Poll`` 對象會有一個額外的屬性: ``choice_count``, 一個關聯`` Choice`` 對象的整數. 注意大多數資料庫引擎需要用括号将子查詢括起來. Django 的 ``select`` 子句則不需要這個括号.
      
where / tables
如果你需要傳遞一個額外的 WHERE 子句 -- 比方進行一個非顯式的連接配接--你可以使用 where 關鍵字參數. 如果你需要在查詢中連接配接其它的表,你可以傳遞它們的名字給 tables 參數.

where 和 tables 都接受一個字元串清單作為它們的值.所有的 where 參數都被 "AND" 到其它的查詢條件中.

舉例來說:

     Poll.objects.filter(
         question__startswith='Who').extra(where=['id IN (3, 4, 5, 20)'])

...翻譯成 SQL 語句就是::

     SELECT * FROM polls_polls WHERE question LIKE 'Who%' AND id IN (3, 4, 5, 20);
      

改變對象

一旦你使用任何上面介紹的方法從資料庫中得到一個對象, 改變這個對象就是相當容易的一件事情了.直接操作這些對象的字段,然後調用 save() 方法儲存它們:

>>> p = Poll.objects.get(id__exact=15)
>>> p.slug = "new_slug"
>>> p.pub_date = datetime.datetime.now()
>>> p.save()
      

建立對象

通過建立一個新的執行個體并調用 save() 儲存之,就可以建立一個新的資料記錄(也就是 INSERT):

>>> p = Poll(slug="eggs",
...                 question="How do you like your eggs?",
...                 pub_date=datetime.datetime.now(),
...                 expire_date=some_future_date)
>>> p.save()
      

一個主鍵值為 None 的對象調用 save() 方法表示這是一個新記錄,應該被插入到資料表中.

通過便利方法(convenience function)可以很容易的建立關聯對象 (比如 Choices):

>>> p.choice_set.create(choice="Over easy", votes=0)
>>> p.choice_set.create(choice="Scrambled", votes=0)
>>> p.choice_set.create(choice="Fertilized", votes=0)
>>> p.choice_set.create(choice="Poached", votes=0)
>>> p.choice_set.count()
4
      

這些 add_choice 方法于下面的函數等價(卻更簡單):

>>> c = Choice(poll_id=p.id, choice="Over easy", votes=0)
>>> c.save()
      

注意當使用這種 add_foo()` 方法時, 你不要給 id 字段提供任何值, 也不要給儲存關系的字段提供任何值.(此處是 poll_id ).

這類 add_FOO() 方法總是傳回剛剛建立的對象.

删除對象

如同你想象的一樣,删除對象的方法是 delete(). 該方法立即删除該對象并傳回 None.比如:

>>> c.delete()
      

通過使用同樣的查詢條件(參數), get_object 和其它查詢方法也可以用來批量删除對象. 比如:

>>> Polls.objects.filter(pub_date__year=2005).delete()
      

此舉将删除2005年的所有民意測驗資料. 注意 delete() 是唯一一個管理器對象不能直接通路的結果集方法. 這提供了一種安全機制,可以避免發生意外事故: 否則 Poll.objects.delete(), 将删除 所有的 投票.

如果你 真的 想删除表中的所有資料,你隻能這麼做:

Polls.objects.all().delete()
      

此舉将從資料庫中删除所有的 Poll 執行個體.

比較對象

要比較兩個 model 對象, 使用标準的 Python 比較運算符,即雙等号: ==. (在幕後進行比較的是兩個對象的 主鍵 的值).

仍然是上面的 Poll 例子, 下面兩個語句是等價的:

some_poll == other_poll
some_poll.id == other_poll.id
      

如果一個 model 的主鍵名字不是 ID, 沒問題, 比較總是發生在主鍵之間,不管它叫什麼名字. 舉例來說, 如果一個 model 的主鍵字段叫 name, 則下面這兩個語句是等價的:

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

其它執行個體方法

除了 save(), delete() 和所有的 add_* 及 get_* 關聯對象方法之外,一個 model 對象可能還擁有下面的部分或全部方法:

get_FOO_display()

如果一個字段有 choices 選項集事, 這個對象将有一個 get_FOO_display() 方法.這裡 FOO 是該字段的名字. 這個方法傳回一個 "human-readable" 的字段值. 舉例來說, 下面的model中:

GENDER_CHOICES = (
     ('M', 'Male'),
     ('F', 'Female'),
)
class Person:
     name = models.CharField(maxlength=20)
     gender = models.CharField(maxlength=1, choices=GENDER_CHOICES)
      

...每個 Person 執行個體會擁有一個 get_gender_display() 的方法. 示例:

>>> p = Person(name='John', gender='M')
>>> p.save()
>>> p.gender
'M'
>>> p.get_gender_display()
'Male'
      

get_next_by_FOO(**kwargs) 和 get_previous_by_FOO(**kwargs)

不存在 null=True 的每個 DateField 和 DateTimeField 自動擁有 get_next_by_FOO() 和 get_previous_by_FOO() 方法, 此處的 FOO 是字段的名字. 它們分别傳回該字段的上一個對象和下一個對象. 如果上一對象或下一對象不存在,則抛出 *DoesNotExist 異常.

這兩個方法均接受可選關鍵字參數, 這些參數應該遵循上文中 "Field 查詢" 中提到的格式.

注意如果遇到相同值的對象, 這些方法會使用 ID 字段進行檢查. 這保證了沒有一條記錄會被跳過或重複記數.參閱 lookup API sample model_ ,那裡有一個完整的例子.

get_FOO_filename()

對一個 FileField 對象來說, 它自動擁有一個 get_FOO_filename() 方法. 這裡 FOO 是字段名,它根據你的 MEDIA_ROOT 設定傳回一個完整的路徑名稱.

注意 ImageField 技術上是 FileField 的一個子類, 是以每個有 ImageField 的 model 自動擁有此方法.

get_FOO_url()

含有 FileField 字段的每個對象自動擁有一個 get_FOO_url() 方法,這裡的 FOO 是字段的名字. 該方法根據你的 MEDIA_URL 設定傳回該檔案的完整 URL ,如果 MEDIA_URL 設定為空, 該方法傳回一個空的字元串.

get_FOO_size()

含有 FileField 字段的每個對象自動擁有一個 get_FOO_filename() 方法, 這裡的 FOO 是字段的名字. 該方法傳回檔案的長度(位元組數).(在背景, Django 使用 os.path.getsize.)

save_FOO_file(filename, raw_contents)

含有 FileField 字段的每個對象自動擁有一個 get_FOO_filename() 方法, 這裡的 FOO 是字段的名字. 該方法使用給定的檔案名将檔案儲存到檔案系統.. 如果同目錄下已經有同名檔案存在,Django 會在檔案名後添加一個下劃線(擴充名之前)直到檔案名有效為止(也就是如果加了下劃線還重名,就再加....直到沒有重名為止).

get_FOO_height() 和 get_FOO_width()

含有 ImageField 字段的每個對象自動擁有 get_FOO_height() 和 get_FOO_width() 方法, 這裡的 FOO 是字段的名字. 它們傳回相應的圖檔高度和寬度(整數,以像素計).

原文位址: http://skandgjxa.blog.163.com/blog/static/141529820101018115135412/