Django快速開發Web 應用程序

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官方文檔,後期會結合實際使用情況加以補充。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章