天天看點

Django快速開發Web 應用程式Django模型層(models)為你的網絡應用提供資料的結構化處理和操作處理

Django模型層(models)為你的網絡應用提供資料的結構化處理和操作處理

###Django最重要的内容:模型(Model)

Django模型類似于傳統的資料庫對象關系映射器,但它使用起來要比ORM簡單快捷很多倍,能夠節省大量的工作。

模型是你的資料的唯一的、權威的資訊源。它包含你所儲存資料的必要字段和行為。通常,每個模型對應資料庫中唯一的一張表。

  • 每個模型都是django.db.models.Model 的一個Python 子類。
  • 模型的每個屬性都表示為資料庫中的一個字段。
  • Django 提供一套自動生成的用于資料庫通路的API;

例如:在models.py中建立兩個實體類:reporter、Artical,這兩個類對應兩個表,并且類的屬性字段與表的字段一一對應。

from django.db import models

class Reporter(models.Model):
    full_name = models.CharField(max_length=70)

	#如果你用的是python3 用__str__即可,該方法是該類的執行個體化對象預設傳回方法
    def __str__(self):              
        return self.full_name
    # 如果用的是python2,用__unicode__
    def __unicode__ (self):              
     return self.full_name

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)

    def __str__(self):              # __unicode__ on Python 2
        return self.headline
           
  • 安裝子產品–生成資料庫表

運作Django指令行工具來自動建立資料庫表

$ python manage.py migrate        
           

使用模型的一些注意事項:

這個表的名稱appName_Reporter,是根據模型中的中繼資料自動生成的,也可以重寫為别的名稱,。

id 字段是自動添加的,但這個行為可以被重寫。詳見自增主鍵字段。

這個例子中的CREATE TABLE SQL 語句使用PostgreSQL 文法格式,要注意的是Django 會根據設定檔案 中指定的資料庫類型來使用相應的SQL 語句。

  • 模型中大量友善的API

接着,你就可以使用一個便捷且功能豐富的Python API來通路你的資料。這些API是即時建立的,不需要代碼生成:

# Import the models we created from our "news" app
>>> from news.models import Reporter, Article

# Python程式中直接使用改模型對象查詢資料
>>> Reporter.objects.all()
[]

# 建立該類的對象到資料庫
>>> r = Reporter(full_name='John Smith')
# Save the object into the database. You have to call save() explicitly.
>>> r.save()
# Now it has an ID.
>>> r.id   #查詢建立reportor的ID(django自動生成的資料庫主鍵id)
1

# 現在再查reportor這張表
>>> Reporter.objects.all()
[<Reporter: John Smith>]   #傳回顯示的資訊是實體類中__str__方法的傳回值。
>>> r.full_name
'John Smith'
# 查詢id是1的reportor
>>> Reporter.objects.get(id=1)
<Reporter: John Smith>
#模糊查詢
>>> Reporter.objects.get(full_name__startswith='John')
<Reporter: John Smith>
>>> Reporter.objects.get(full_name__contains='mith')
<Reporter: John Smith>
#查詢不存在的id
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
    ...
DoesNotExist: Reporter matching query does not exist.
#報錯對象找不到

           

生成動态的管理界面:它不隻是一個腳手架 ,而是一所完整的房子

一旦你的模型定義完畢之後,Django能自動建立一個專業的、可以用于生産環境的 管理界面 – 可以讓認證的使用者添加、修改和删除對象的一個站點。隻需簡單地在admin site中注冊你的模型即可:

#mysite/news/models.py

from django.db import models

class Article(models.Model):
    pub_date = models.DateField()
    headline = models.CharField(max_length=200)
    content = models.TextField()
    reporter = models.ForeignKey(Reporter)
mysite/news/admin.py
from django.contrib import admin

from . import models

admin.site.register(models.Article)
           

這裡的原則是,你的網站是由從業人員或客戶,或者也許隻是你編輯 - 并且你不想僅僅為了管理内容而建立後端接口。

建立Django應用的一個典型工作流程是建立模型然後盡快地讓admin sites啟動和運作起來, 這樣您的員工(或客戶)能夠開始錄入資料。 然後,開發向公衆展現資料的方式。

設計你的URLs

對于高品質的Web 應用來說,使用簡潔、優雅的URL 模式是一個非常值得重視的細節。Django鼓勵使用漂亮的URL設計且不會像.php或.asp一樣把亂七八糟的東西放到URLs裡面,.

為了給一個應用設計URLs,你需要建立一個叫做URLconf的Python子產品。這其實是你應用的目錄,它包含URL模式與Python回調函數間的一個簡單映射。 URLconfs 還用作從Python代碼中解耦URLs。

下面是針對上面Reporter/Article例子URLconf 可能的樣子:

# mysite/news/urls.py
from django.conf.urls import url

from . import views

urlpatterns = [
    url(r'^articles/([0-9]{4})/$', views.year_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
    url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
           

上面的代碼将URLs映射作為簡單的正規表達式映射到Python的回調函數(視圖)。正規表達式通過圓括号來“捕獲”URLs中的值。 當一個使用者請求一個頁面時,Django将按照順序去比對每一個模式,并停在第一個比對請求的URL上。 (如果沒有比對到, Django将調用一個特殊的404視圖。)整個過程是極快的,因為正規表達式在加載時就已經編譯好了。

一旦有一個正規表達式比對上了,Django 将導入和調用對應的視圖,它其實就是一個簡單的Python函數。 每個視圖将得到一個request對象 —— 它包含了request 的metadata(中繼資料) —— 和正規表達式所捕獲到的值。

例如,如果一個使用者請求了URL “/articles/2005/05/39323/”,Django将調用函數news.views.article_detail(request, ‘2005’, ‘05’, ‘39323’)。

編寫視圖

每個視圖隻負責兩件事中的一件:傳回一個包含請求的頁面内容的 HttpResponse對象, 或抛出一個異常如Http404。 剩下的就看你了。

通常,一個視圖會根據參數來檢索資料、加載一個模闆然後使用檢索出來的資料渲染模闆。下面是上文year_archive的一個視圖例子:

# mysite/news/views.py
from django.shortcuts import render

from .models import Article

def year_archive(request, year):
    a_list = Article.objects.filter(pub_date__year=year)
    context = {'year': year, 'article_list': a_list}
    return render(request, 'news/year_archive.html', context)
           

這個例子使用了Django的模闆系統,它具有幾個強大的功能,但是仍然努力做到了即使對于非程式設計人員也能保持足夠的簡單。

###設計模闆

上面的代碼加載news/year_archive.html模闆。

Django有一個模闆搜尋路徑,它允許您最大限度地減少模闆之間的備援。在你的Django設定中,你可以通過DIRS指定一個查找模闆的目錄清單。如果這個模闆沒有在第一個目錄中,那麼它會去查找第二個,以此類推。

讓我們假設news/year_archive.html模闆已經找到。它看起來可能是下面這個樣子:

# mysite/news/templates/news/year_archive.html
{% extends "base.html" %}

{% block title %}Articles for {{ year }}{% endblock %}

{% block content %}
<h1>Articles for {{ year }}</h1>

{% for article in article_list %}
    <p>{{ article.headline }}</p>
    <p>By {{ article.reporter.full_name }}</p>
    <p>Published {{ article.pub_date|date:"F j, Y" }}</p>
{% endfor %}
{% endblock %}
           

變量使用兩對大括号包圍。 {{ article.headline }}表示“輸出 article的headline屬性”。但是點符号不僅用于屬性查找。它們還用于字典的鍵值查找、索引查找和函數調用。

注意{{ article.pub_date|date:“F j, Y” }}使用Unix風格的“管道”(“|”字元)。這叫做模闆過濾器,它是過濾變量值的一種方式。 在本例中,date過濾器格式化Python的datetime對象成給定的格式(正如在PHP中日期函數)。

你可以無限制地串聯使用多個過濾器。 你可以編寫自定義的目标過濾器。你可以編寫自定義的模闆标簽,在幕後運作自定義的Python代碼。

最後,Django使用“模闆繼承”的概念。這就是{% extends “base.html” %}所做的事。它表示“首先載入‘base’ 模闆,該模闆中定義了一系列block,然後使用接下來的(存在于繼承模闆)blocks填充這些blocks”。簡而言之,模闆繼承讓你大大減少模闆間的備援内容:每個模闆隻需要定義它獨特的部分。

下面是“base.html”模闆可能的樣子,它使用了靜态檔案:

mysite/templates/base.html

{% load staticfiles %}
<html>
<head>
    <title>{% block title %}{% endblock %}</title>
</head>
<body>
    <img src="{% static "images/sitelogo.png" %}" alt="Logo" />
    {% block content %}{% endblock %}
</body>
</html>
           

簡單地說,它定義網站的外觀(使用網站的logo ),并提供“空洞”讓子模闆填充。這使站點的重構變得非常容易,隻需改變一個檔案 —— base模闆。

它還可以讓你利用不同的基礎模闆并重用子模闆建立一個網站的多個版本。Django 的建立者已經利用這一技術來創造了顯著不同的手機版本的網站 —— 隻需建立一個新的基礎模闆。

請注意,如果你喜歡其它模闆系統,你可以不使用Django的模闆系統。 雖然Django的模闆系統與Django的模型層內建得特别好,但并沒有強制你使用它。同理,你也可以不使用Django的資料庫API。 你可以使用任何你想要的方法去操作資料,包括其它資料庫抽象層,讀取 XML 檔案或者直接從磁盤中讀取檔案。Django的每個組成部分 —— 模型、視圖和模闆都可以解耦。

PS:以上内容取自python官方文檔,後期會結合實際使用情況加以補充。