Django06模型和數據庫

首先,讓我們看看Rango的需求.下面列出了Rango數據關鍵的幾個需求.

  • Rango實際上是一個網頁目錄 - 一個包含其他我站鏈接的網站
  • 有許多不同網站的目錄,每個目錄中包含許多鏈接.我們在第二章假設1對多關系 看下面的ER圖.
  • 一個目錄要有名字,訪問數和鏈接.
  • 一個頁面要有目錄,標題,URL和一些視圖

1. 告訴Django你的數據庫

在你創造任何模型之前都要對你的數據庫進行設置
Django會自動在settings.py里添加一個叫做DATABASES的字典.它包含如下.

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
    }
}

能看到默認用SQLite3作為后端數據庫.SQLite是個輕量級的數據庫對我們開發很有用.我們僅僅需要設置DATABASE_PATH里的NAME鍵值對.其他引擎需要USER,PASSWORD,HOST和PORT等關鍵字

2. 創建模型

讓我們為Rango創建兩個數據模型.

在rango/models.py里,我們定義兩個繼承自djnago.db.models.Model的類.這兩個類分別定義目錄和頁面.定義Category和Page如下

from django.db import models

# Create your models here.

class Category(models.Model):
    name = models.CharField(max_length=128, unique=True)
    def __str__(self):
        return self.name

class Page(models.Model):
    category = models.ForeignKey(Category)
    title = models.CharField(max_length=128)
    url = models.URLField()
    views = models.IntegerField(default=0)
    def __str__(self):
        return self.title

當你定義了一個模型,你需要制定可選參數的屬性以及相關的類型列表.Django提供了許多內建字段.一些常用的如下.

  • CharField,存儲字符數據的字段(例如字符串).max_length提供了最大長度.
  • URLField,和CharField一樣,但是它存儲資源的URL.你也可以使用max_length參數.
  • 'IntegerField',存儲整數.
  • DateField,存儲Python的datetime.date.

每個字段都有一個unique屬性.如果設置為True,那么在整個數據庫模型里它的字段里的值必須是唯一的.例如,我們上面定義的Category模型.name字段被設置為unique - 所以每一個目錄的名字都必須是唯一的
如果你想把這個字段作為數據庫的關鍵字會非常有用.你可以為每個字段設置一個默認值(default='value'),也可以設置成NULL(null=True).
Django也提供了連接模型/表的簡單機制.這個機制封裝在3個字段里,如下.

  • ForeignKey, 創建1對多關系的字段類型.
  • OneToOneField,定義一個嚴格的1對1關系字段類型.
  • ManyToManyFeild,當以多對多關系字段類型.
    從上面我們的例子,Page中category字段是ForeignKey類型.所以我們可以創建一個1對多關系的Category模型/表,這個Category會作為構造函數的一個參數.Django會自動的為每個模型表中創建ID字段.所以你不同為每個模型創建主鍵 - 它已經為你做好了!

3. 設置數據庫并創建管理員

如果還沒有設置數據庫那么需要通過migrate命令來設立.

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, contenttypes, auth, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying sessions.0001_initial... OK

你是否還記得在settings.py文件里設置的INSTALLED_APPS列表,它會初始化創建這些app的圖表,例如auth,admin等等.在你的項目根目錄里會創建db.sqlite文件.

  • 現在你可以創建一個管理員來管理數據庫.
    $ python manage.py createsuperuser

4. 創建/上傳模型/表

當你更改模型的時候,你需要通過makemigrations進行修改,所以對于rango,我們需要:

$ python manage.py makemigrations rango
Migrations for 'rango':
  0001_initial.py:
    - Create model Category
    - Create model Page

如果你檢查rango/migrations文件,你會發現會創建一個叫做0001_initial.py的python腳本.如果想要SQL命令去執行遷移,那么可以用下面的命令python manage.py sqlmigrate <app_name> <migration_no.我們上面的遷移數字是0001,所以我們輸入python manage.py sqlmigrate rango 0001,讓我們試試看.
現在讓我們應用這些遷移(基于創建數據庫圖表).

$ python manage.py migrate
Operations to perform:
  Apply all migrations: admin, rango, contenttypes, auth, sessions
Running migrations:
  Applying rango.0001_initial... OK

當你添加已存在的模型,你需要重復運行python manage.py makemigrations <app_name>命令然后再運行python manage.py migrate.

5. Shell

shell
# Import the Category model from the Rango application
>>> from rango.models import Category
# Show all the current categories
>>> print Category.objects.all()
[] # Returns an empty list (no categories have been defined!)
# Create a new category object, and save it to the database.
>>> c = Category(name="Test")
>>> c.save()
# Now list all the category objects stored once more.
>>> print Category.objects.all()
[<Category: test>] # We now have a category called 'test' saved in the database!
# Quit the Django shell.
>>> quit()

在例子中我們首先導入我們需要操作的模型.然后打印出存在的目錄,在這里因為我們的圖表是空所以輸出也是空.然后創建并儲存一個目錄,打印.

6. 設置管理界面

Django最突出的一個特性就是它提供內建的網頁管理界面,用來瀏覽和編輯存儲在模型的數據,也可以與數據庫圖表交互.在settings.py文件里,注意到有一個默認安裝的django.contib.adminapp,而且你的urls.py里也默認增加了admin/匹配.

開啟Django服務:
$ python manage.py runserver
訪問127.0.0.1:8000/admin.可以用先前設置管理員賬戶的用戶名和密碼來登錄Django管理界面.管理界面只包含Groups和Users圖表以我們需要讓Django包含rango模塊.所以打開rango/admin.py輸入如下代碼:

from django.contrib import admin
from rango.models import Category, Page
admin.site.register(Category)
admin.site.register(Page)

上面代碼會為我們在管理界面注冊模型.如果我們想要其他模型,可以在admin.stie.register()函數里傳遞模型作為參數.

完成之后重新訪問127.0.0.1:8000/admin/,你想回看到如下圖案.

效果圖

7. 創建Population Script

往數據庫里輸入數據會非常麻煩.許多開發者會隨機的往數據庫里輸入測試數據.如果你在一個小的開發團隊里,每個人都得傳點數據.最好是寫一個腳本而不是每個人單獨的上傳數據,這樣就可以避免垃圾數據的產生.所以我們需要為你的數據庫創建 population script.這個腳本自動的為你的數據庫生成測試數據.

我們需要在Django項目的根目錄里創建population script(例如<workspace>/tango_with_django_project/).創建populate_rango.py文件代碼如下.

import os
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tango_with_django_project.settings')

import django
django.setup()

from rango.models import Category, Page


def populate():
    python_cat = add_cat('Python')

    add_page(cat=python_cat,
        title="Official Python Tutorial",
        url="http://docs.python.org/2/tutorial/")

    add_page(cat=python_cat,
        title="How to Think like a Computer Scientist",
        url="http://www.greenteapress.com/thinkpython/")

    add_page(cat=python_cat,
        title="Learn Python in 10 Minutes",
        url="http://www.korokithakis.net/tutorials/python/")

    django_cat = add_cat("Django")

    add_page(cat=django_cat,
        title="Official Django Tutorial",
        url="https://docs.djangoproject.com/en/1.5/intro/tutorial01/")

    add_page(cat=django_cat,
        title="Django Rocks",
        url="http://www.djangorocks.com/")

    add_page(cat=django_cat,
        title="How to Tango with Django",
        url="http://www.tangowithdjango.com/")

    frame_cat = add_cat("Other Frameworks")

    add_page(cat=frame_cat,
        title="Bottle",
        url="http://bottlepy.org/docs/dev/")

    add_page(cat=frame_cat,
        title="Flask",
        url="http://flask.pocoo.org")

    # Print out what we have added to the user.
    for c in Category.objects.all():
        for p in Page.objects.filter(category=c):
            print ("- {0} - {1}".format(str(c), str(p)))

def add_page(cat, title, url, views=0):
    p = Page.objects.get_or_create(category=cat, title=title, url=url, views=views)[0]
    return p

def add_cat(name):
    c = Category.objects.get_or_create(name=name)[0]
    return c

# Start execution here!
if __name__ == '__main__':
    print ("Starting Rango population script...")
    populate()

$ python populate_rango.py執行腳本

效果圖

8. 基本流程

流程圖

9. 練習

練習

添加views和likes的代碼:

代碼

populate.py的修改

修改

定制管理界面

admin

最終效果

1
2
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,106評論 6 542
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,441評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 178,211評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,736評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,475評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,834評論 1 328
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,829評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 43,009評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,559評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,306評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,516評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,038評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,728評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,132評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,443評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,249評論 3 399
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,484評論 2 379

推薦閱讀更多精彩內容