(4)Django框架學習-Model篇


Model使用

首先安裝MySQL的python連接驅動,windows下安裝可下下載,對應python-2.7:
https://code.google.com/p/soemin/downloads/detail?name=MySQL-python-1.2.3.win32-py2.7.exe&can=2&q=
 
簡單的,先展示在view中使用mysql數據庫操作
from django.shortcuts import render_to_response
import MySQLdb

def book_list(request) :
    db = MySQLdb.connect(user = 'me', db = 'mydb', passwd = 'secret', host = 'localhost')
    cursor = db.cursor()
    cursor.execute( 'SELECT name FROM books ORDER BY name')
    names = [row[ 0] for row in cursor.fetchall()]
    db.close()
    return render_to_response( 'book_list.html', { 'names' : names})
 
以上的做法比較原始,也有一些弊端:
1. 硬編碼數據庫連接參數,理想情況下,這些應該放到配置文件中去
2. 固定流程,總是打開連接,創建游標,關閉連接這幾步,重復代碼太多
3. 綁定mysql數據庫,如果要切換別的數據庫,修改太多了,要改連接參數,沒准SQL語句也要修改
 
而Django數據庫API就是為了解決以上問題而生。
from django.shortcuts import render_to_response
from mysite.books.models import Book

def book_list(request) :
    books = Book.objects.order_by( 'name')
return render_to_response( 'book_list.html', { 'books' : books})
 
首先要在settings.py文件進行數據庫的設定
DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'.
        'NAME': 'test', # 數據庫名稱,如果使用sqlite3,則輸入數據庫文件路徑,如'/home/django/mydata.
        'USER': 'root', # Not used with sqlite3.
        'PASSWORD': 'admin', # Not used with sqlite3.
        'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
        'PORT': '', # Set to empty string for default. Not used with sqlite3.
    }
}
 
一旦設置好數據庫信息,可以使用python manage.py shell進行測試
>>> from django.db import connection
>>> cursor = connection.cursor()
如果不報錯,則說明配置正常。
 
下面簡單介紹一下project和app之間的區別:
1. project是一系列app集合的一個實例,外加對這些app的配置信息。
確切地說,project只需要提供一個配置文件,包括數據庫連接信息,所安裝的app的列表,模板路徑等等
2. app是一系列Django提供的功能的可重用的集合,一般包括在同一個包中的modesl, views。
例如,一個Django project可以由很多個app組成,如一個評論系統,一個后台管理系統等,所有這些app
都可以在不同的project中重用,是獨立的,當然也要看你的設計了。。。
 
然而app不是非要不可的,view+template+urlconf就足可以組建project,但是為了追求可重用性,以及想使用
Django強大的database level api--model,就一定要創建app,使用以下命令:
python manage.py startapp books
 
有人認為在python中重新定義一個數據表中的字段信息,是不是有點冗余,如果直接使用數據庫本身的自省操作
在運行時,來確定數據模型的話,是不是更方便?
答案是錯誤的,
1. 后者因為是在運行時,如果每一個請求都在去自省一下數據庫的表結構,這樣就會產生額外的開銷,
給系統造成負擔。
2. 再者,把表結構寫在python代碼,容易管理和操作。
3. 然后,數據庫中的數據類型比較單一,而Django中的數據類型豐富,比如郵件地址類型,網址類型等,
都可以提高生產力。。。
 
用python代碼來表示數據表信息的做法有一個缺點就是一定要保持和數據庫表信息一致,如果一方修改,
都需要進行修改。
 
使用model的一般步驟:
1. 在app的models文件中創建model子類
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()
2. 然后在settings.py中注冊你的app
MIDDLEWARE_CLASSES = (
    # 'django.middleware.common.CommonMiddleware',
    # 'django.contrib.sessions.middleware.SessionMiddleware',
    # 'django.contrib.auth.middleware.AuthenticationMiddleware',
)
 
INSTALLED_APPS = (
    # 'django.contrib.auth',
    # 'django.contrib.contenttypes',
    # 'django.contrib.sessions',
    # 'django.contrib.sites',
    'books', #注意加上這個逗號來區分元組類型,同時記得是要用引號。。。
)
3. 可以使用命令來驗證你的設置,0 errors代表正確
python manage.py validate
 
4. 通過model類定義來創建數據庫表,可以使用命令:
python manage.py sqlall books #打印出創建相應的數據表的SQL語句
python manage.py syncdb #直接執行SQL語句,只用來檢查是否表存在,如果沒有,就創建新的表,
如果model中的數據有改動,這一句執行就沒有用。
 
5. 使用model進行簡單的數據表插入操作, Django直到save()才是真正地寫入數據庫。
python manage.py shell
>>> from books.models import Publisher
>>> p1 = Publisher(name='Apress', address='2855 Telegraph Avenue',
... city='Berkeley', state_province='CA', country='U.S.A.',
... website='http://www.apress.com/')
>>> p1.save()
使用manager進行查詢
>>> publisher_list = Publisher.objects.all() #Publisher.objects返回的就是一個管理器
>>> publisher_list
[<Publisher: Publisher object>, <Publisher: Publisher object>]
這樣就可以進行取出記錄數據的操作,或者是你自己定義的其它邏輯操作
>>> publisher_list[0].address
u'2855 Tele Avenur'
 
如果想直接寫入數據庫,不用save(),則使用管理器的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/')
 
6. 在model的類中,增加__unicode__()函數,來代表各個類的字符串表示信息。相當於java中的toString()
def __unicode__(self):
    return self.name
>>>[<Publisher: Apress>, <Publisher: O'Reilly>]
 
7. 更新的操作,就是簡單的賦個新值,再save()一下
不過這樣做效率一般,manager有update函數專門用於更新操作
>>> Publisher.objects.filter(id=52).update(name='Apress Publishing')
 
8. 條件選擇操作,使用manager中的filter函數,返回的是QuerySet對象,類似結果集對象
>>> Publisher.objects.filter(name='Apress')
[<Publisher: Apress>]
 
更復雜的條件選擇操作,是使用Django特有的lookup type修飾詞來實現
>>> Publisher.objects.filter(name__contains="press")
[<Publisher: Apress>]
__contains:類似SQL語句中的like的模糊匹配操作:
WHERE name LIKE '%press%';
 
如果想獲取單一的對象,使用get()函數,如果返回的對象有多個,就報錯MultipleObjectsReturned。
如果返回值為空,也報錯DoesNotExist。
>>> a = Publisher.objects.get(name="Apress")
>>> a
<Publisher: Apress>
>>> a.address
u'2855 Tele Avenur'
也可以進行取出記錄數據的相應操作,就相當於取出了一個Publisher記錄的對象。
 
9. 排序操作
>>> Publisher.objects.order_by("state_province", "address")
[<Publisher: Apress>, <Publisher: O'Reilly>]
 
>>> Publisher.objects.order_by("-name") #'-'表示倒序
 
QuerySet也可以像列表那樣用索引取值
Publisher.objects.order_by("address")[1]
但是不支持負數
Publisher.objects.order_by("address")[-1]
不過可以用倒序來表示:
Publisher.objects.order_by("-address")[0]
 
10. 刪除記錄操作
對於單個model類或者是QuerySet類都有對應的delete()函數
>>> p = Publisher.objects.get(name="O'Reilly")
>>> p.delete()
>>> Publisher.objects.filter(country='USA').delete()
>>> Publisher.objects.all().delete()#如果要清空數據表,一就要顯示地調用all(),再delete

 

 

 

 






免責聲明!

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



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