(轉)Django ====> models學習


轉。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

五、數據庫訪問
1、基本數據訪問
[root@pxe-svr mysite]# ./manage.py shell
>>> from books.models import Publisher
#導入Publisher模型類
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
#創建Publisher類的實例p1
>>> p1.save()
#調用實例p1的save()方法將數據存入數據庫,Django 會在后台執行一條 INSERT 語句。
如果需要一步完成對象的創建與存儲至數據庫,就使用`` objects.create()`` 方法.
>>> p1 = Publisher.objects.create(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
獲取
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Publisher object>]
2、添加模塊的字符串表現
當我們打印整個publisher列表時,我們沒有得到想要的有用信息,無法把````對象區分開來:
[root@pxe-svr mysite]# vim books/models.py
from django.db import models

# Create your models here.
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()

def __unicode__(self):
return self.name


class Author(models.Model):
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=40)
email = models.EmailField()

def __unicode__(self):
return u'%s %s' % (self.first_name, self.last_name)

class Book(models.Model):
title = models.CharField(max_length=100)
authors = models.ManyToManyField(Author)
publisher = models.ForeignKey(Publisher)
publication_date = models.DateField()

def __unicode__(self):
return self.title
__unicode__() 方法可以進行任何處理來返回對一個對象的字符串表示。 Publisher和Book對象的__unicode__()方法簡單地返回各自的名稱和標題,
Author對象的__unicode__()方法則稍微復雜一些,它將first_name和last_name字段值以空格連接后再返回。
對__unicode__()的唯一要求就是它要返回一個unicode對象 如果`` __unicode__()`` 方法未返回一個Unicode對象,而返回比如說一個整型數字,
那么Python將拋出一個`` TypeError`` 錯誤,並提示:”coercing to Unicode: need string or buffer, int found” 。
unicode對象就是一個Python字符串.
Unicode對象並沒有編碼。它們使用Unicode,一個一致的,通用的字符編碼集。 當你在Python中處理Unicode對象的時候,你可以直接將它們混合使用和互相匹配而不必去考慮編碼細節。
Django 在其內部的各個方面都使用到了 Unicode 對象。 模型 對象中,檢索匹配方面的操作使用的是 Unicode 對象,視圖 函數之間的交互使用的是 Unicode 對象,
模板的渲染也是用的 Unicode 對象。通常,我們不必擔心編碼是否正確,后台會處理的很好。
為了讓我們的修改生效,先退出Python Shell,然后再次運行 python manage.py shell 進入。(這是保證代碼修改生效的最簡單方法。)
>>> publisher_list = Publisher.objects.all()
>>> publisher_list
[<Publisher: Apress>

3、插入和更新數據
1)插入
>>> from books.models import Publisher
>>> p = Publisher(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
>>> p.save()
>>> p.id
4L
#因為 Publisher 模型有一個自動增加的主鍵 id ,所以第一次調用 save() 還多做了一件事: 計算這個主鍵的值並把它賦值給這個對象實例:

>>> p = Publisher.objects.create(name='Apress', address='2855 Telegraph Avenue', city='Berkeley', state_province='CA', country='U.S.A.',website='http://www.apress.com/')
>>> p.id
5L
這個方法也會有實例屬性id
2)更新
>>>p = Publisher.objects.get(name='Apress')
>>> p.name='jin'
>>> p.save
這里不爽的是需要原來創建的那個實例
執行的 save() 相當於下面的SQL語句:
UPDATE books_publisher SET
name = 'jin',
address = '2855 Telegraph Ave.',
city = 'Berkeley',
state_province = 'CA',
country = 'U.S.A.',
website = 'http://www.apress.com'
WHERE id = 5;
注意,並不是只更新修改過的那個字段,所有的字段都會被更新。 這個操作有可能引起競態條件,這取決於你的應用程序。

3)更新多個對象
Django 模型的save()方法更新了不僅僅是name列的值,還有更新了所有的列。 若name以外的列有可能會被其他的進程所改動的情況下,只更改name列顯然是更加明智的。
更改某一指定的列,我們可以調用結果集(QuerySet)對象的update()方法:
>>> Publisher.objects.filter(id=7).update(country='USA')
1L
等同
UPDATE books_publisher
SET country='USA'
WHERE id = 52;
update()方法會返回一個整型數值,表示受影響的記錄條數。 在上面的例子中,這個值是2。
update()方法對於任何結果集(QuerySet)均有效,這意味着你可以同時更新多條記錄

4、選擇對象 查詢
1)基本查詢數據 Publisher.objects.all()
>>>Publisher.objects.all()
[<Publisher: Apress>, <Publisher: O'Reilly>]
QuerySet 對象,仿真列表
這相當於這個SQL語句:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher;
注意到Django在選擇所有數據時並沒有使用 SELECT* ,而是顯式列出了所有字段。
設計的時候就是這樣: SELECT* 會更慢,而且最重要的是列出所有字段遵循了Python 界的一個信條: 明言勝於暗示。
Publisher.objects.all() 這行的每個部分:
首先,已定義的模型 Publisher
然后,是objects屬性。 它被稱為管理器
所有的模型都自動擁有一個 objects 管理器;你可以在想要查找數據時使用它。
最后,還有 all() 方法。這個方法返回返回數據庫中所有的記錄。 盡管這個對象 看起來 象一個列表(list),它實際是一個 QuerySet 對象, 這個對象是數據庫中一些記錄的集合。
所有的數據庫查找都遵循這個通用模式:
2)數據過濾 Publisher.objects.filter()
>>> Publisher.objects.filter(name='jin')
[<Publisher: jin>]
filter() 根據關鍵字參數來轉換成 WHERE SQL語句。
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE name = 'jin';
傳遞多個參數到 filter() 來縮小選取范圍:
>>> Publisher.objects.filter(country="U.S.A.", state_province="CA")
[<Publisher: jin>, <Publisher: Apress>]
多個參數會被轉換成 AND SQL從句,
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = 'U.S.A.'
AND state_province = 'CA';
注意,SQL缺省的 = 操作符是精確匹配的
LIKE方式匹配
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
在 name 和 contains 之間有雙下划線。和Python一樣,Django也使用雙下划線來表明會進行一些魔術般的操作。這里,contains部分會被Django翻譯成LIKE語句:
3)、獲取單個對象。Publisher.objects.get()
上面的例子中`` filter()`` 函數返回一個記錄集,這個記錄集是一個列表。 相對列表來說,有些時候我們更需要獲取單個的對象, `` get()`` 方法就是在此時使用的:
>>> Publisher.objects.get(name="Apress")
這樣,就返回了單個對象,而不是列表(更准確的說,QuerySet)。 所以,如果結果是多個對象,會導致拋出異常:
<Publisher: Apress>
Publisher.objects.get(country="U.S.A.")
如果查詢沒有返回結果也會拋出異常:
DoesNotExist 異常 是 Publisher 這個 model 類的一個屬性,即 Publisher.DoesNotExist。在你的應用中,你可以捕獲並處理這個異常,像這樣:
try:
p = Publisher.objects.get(name='Apress')
except Publisher.DoesNotExist:
print "Apress isn't in the database yet."
else:
print "Apress is in the database."
4)數據排序 Publisher.objects.order_by()
在你的 Django 應用中,你或許希望根據某字段的值對檢索結果排序,比如說,按字母順序。
>>> Publisher.objects.all()
[<Publisher: jin>, <Publisher: Apress>]
>>> Publisher.objects.order_by("name")
[<Publisher: Apress>, <Publisher: jin>]
SQL語句里多了指定排序的部分:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name;
對多個字段進行排序
Publisher.objects.order_by("state_province", "address")
還可以指定逆向排序,在前面加一個減號 - 前綴:
類似SQL :ORDER BY name DESC;
>>> Publisher.objects.order_by("-name")
[<Publisher: jin>, <Publisher: Apress>]

5)在模型的缺省排序方式
盡管很靈活,但是每次都要用 order_by() 顯得有點啰嗦。 大多數時間你通常只會對某些 字段進行排序。 在這種情況下,Django讓你可以指定模型的缺省排序方式:
class Publisher(models.Model):
name = models.CharField(max_length=30)
address = models.CharField(max_length=50)
city = models.CharField(max_length=60)
state_province = models.CharField(max_length=30)
country = models.CharField(max_length=50)
website = models.URLField()

def __unicode__(self):
return self.name

class Meta:
rdering = ['name']
新的概念。 class Meta,內嵌於 Publisher 這個類的定義中(如果 class Publisher 是頂格的,那么 class Meta 在它之下要縮進4個空格--按 Python 的傳統 )。
你可以在任意一個模型類中使用 Meta 類,來設置一些與特定模型相關的選項。
如果你設置了這個選項,那么除非你檢索時特意額外地使用了 order_by(),否則,當你使用 Django 的數據庫 API 去檢索時,Publisher對象的相關返回值默認地都會按 name 字段排序。
>>> from books.models import Publisher
>>> Publisher.objects.all()
[<Publisher: Apress>, <Publisher: jin>]

6)連鎖查詢Publisher.objects.filter().order_by() #過濾后再排序
我們已經知道如何對數據進行過濾和排序。 當然,通常我們需要同時進行過濾和排序查詢的操作。 因此,你可以簡單地寫成這種“鏈式”的形式:
>>> Publisher.objects.filter(country="U.S.A.").order_by("-name")
[<Publisher: jin>, <Publisher: Apress>]
轉換成SQL查詢就是 WHERE 和 ORDER BY 的組合:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
WHERE country = 'U.S.A'
ORDER BY name DESC;
7)限制返回的數據
另一個常用的需求就是取出固定數目的記錄。可以使用標准的Python列表裁剪語句:
Publisher.objects.order_by('name')[0]
這相當於:
SELECT id, name, address, city, state_province, country, website
FROM books_publisher
ORDER BY name
LIMIT 1;
類似的,可以用Python的range-slicing語法來取出數據的特定子集:
Publisher.objects.order_by('name')[0:2]
超出邊界 不會報錯
注意,不支持Python的負索引(negative slicing):
雖然不支持負索引,但是我們可以使用其他的方法。 比如,稍微修改 order_by() 語句來實現:
>>> Publisher.objects.order_by('-name')[0]

5、刪除對象
刪除數據庫中的對象只需調用該對象的delete()方法即可:
>>> p = Publisher.objects.get(name="jin")
>>> p.delete()
>>> Publisher.objects.all()
[<Publisher: Apress>]
同樣我們可以在結果集上調用delete()方法同時刪除多條記錄。這一點與我們上一小節提到的update()方法相似:
>>> Publisher.objects.filter(country='USA').delete() #有條件刪除
>>> Publisher.objects.all().delete() #刪除所有數據
>>> Publisher.objects.all()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM