Django 一覽¶
因為 Django 是在快節奏的新聞編輯室環境中開發的,它被設計成可以快速且輕鬆地完成常見的 Web 開發任務。以下是如何使用 Django 編寫資料庫驅動的 Web 應用程式的非正式概述。
本文檔的目標是提供足夠的技術細節,讓您了解 Django 的運作方式,但這並非教程或參考資料 - 但我們兩者都有!當您準備好開始專案時,您可以從教學開始或直接深入更詳細的文件。
設計您的模型¶
雖然您可以在沒有資料庫的情況下使用 Django,但它帶有一個物件關聯映射器,您可以在其中以 Python 程式碼描述資料庫佈局。
資料模型語法提供了許多豐富的方法來表示您的模型 – 到目前為止,它已經解決了多年來的資料庫架構問題。這是一個快速範例
news/models.py
¶from django.db import models
class Reporter(models.Model):
full_name = models.CharField(max_length=70)
def __str__(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, on_delete=models.CASCADE)
def __str__(self):
return self.headline
安裝它¶
接下來,執行 Django 命令列公用程式以自動建立資料庫表
$ python manage.py makemigrations
$ python manage.py migrate
...\> py manage.py makemigrations
...\> py manage.py migrate
makemigrations
命令會查看您所有可用的模型,並為任何尚不存在的表建立遷移。migrate
執行遷移並在您的資料庫中建立表,以及選擇性地提供更豐富的架構控制。
享受免費的 API¶
有了它,您就有一個免費且豐富的Python API 來存取您的資料。API 是動態建立的,不需要程式碼生成
# Import the models we created from our "news" app
>>> from news.models import Article, Reporter
# No reporters are in the system yet.
>>> Reporter.objects.all()
<QuerySet []>
# Create a new Reporter.
>>> 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
1
# Now the new reporter is in the database.
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>
# Fields are represented as attributes on the Python object.
>>> r.full_name
'John Smith'
# Django provides a rich database lookup API.
>>> 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>
>>> Reporter.objects.get(id=2)
Traceback (most recent call last):
...
DoesNotExist: Reporter matching query does not exist.
# Create an article.
>>> from datetime import date
>>> a = Article(
... pub_date=date.today(), headline="Django is cool", content="Yeah.", reporter=r
... )
>>> a.save()
# Now the article is in the database.
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>
# Article objects get API access to related Reporter objects.
>>> r = a.reporter
>>> r.full_name
'John Smith'
# And vice versa: Reporter objects get API access to Article objects.
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>
# The API follows relationships as far as you need, performing efficient
# JOINs for you behind the scenes.
# This finds all articles by a reporter whose name starts with "John".
>>> Article.objects.filter(reporter__full_name__startswith="John")
<QuerySet [<Article: Django is cool>]>
# Change an object by altering its attributes and calling save().
>>> r.full_name = "Billy Goat"
>>> r.save()
# Delete an object with delete().
>>> r.delete()
動態管理介面:它不僅僅是腳手架,而是整個房子¶
一旦定義了模型,Django 可以自動建立專業的、可生產的管理介面 - 一個允許通過身份驗證的使用者新增、變更和刪除物件的網站。唯一需要的步驟是在管理網站中註冊您的模型
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, on_delete=models.CASCADE)
news/admin.py
¶from django.contrib import admin
from . import models
admin.site.register(models.Article)
這裡的理念是您的網站由員工或客戶編輯,或者可能只是您 - 而且您不想為了管理內容而處理建立後端介面。
建立 Django 應用程式的一個典型工作流程是建立模型並盡快啟動和執行管理網站,以便您的員工(或客戶)可以開始填寫資料。然後,開發向公眾呈現資料的方式。
設計您的 URL¶
乾淨、優雅的 URL 方案是高品質 Web 應用程式中的一個重要細節。Django 鼓勵優美的 URL 設計,並且不會在 URL 中放入任何雜亂,例如 .php
或 .asp
。
要為應用程式設計 URL,您可以建立一個名為 URLconf 的 Python 模組。它是您應用程式的目錄,包含 URL 模式和 Python 回呼函數之間的映射。URLconf 也用於將 URL 與 Python 程式碼分離。
以下是上述 Reporter
/Article
範例的 URLconf 可能的樣子
news/urls.py
¶from django.urls import path
from . import views
urlpatterns = [
path("articles/<int:year>/", views.year_archive),
path("articles/<int:year>/<int:month>/", views.month_archive),
path("articles/<int:year>/<int:month>/<int:pk>/", views.article_detail),
]
上面的程式碼將 URL 路徑映射到 Python 回呼函數(「檢視」)。路徑字串使用參數標籤從 URL 中「捕獲」值。當使用者請求頁面時,Django 會依序執行每個路徑,並在第一個符合請求 URL 的路徑處停止。(如果沒有一個匹配,Django 會呼叫特殊情況的 404 檢視)。這非常快,因為路徑會在載入時編譯為正規表示式。
一旦其中一個 URL 模式匹配,Django 會呼叫給定的檢視,這是一個 Python 函數。每個檢視都會傳遞一個請求物件(其中包含請求中繼資料)和在模式中捕獲的值。
例如,如果使用者請求 URL「/articles/2005/05/39323/」,Django 會呼叫函數 news.views.article_detail(request, year=2005, month=5, pk=39323)
。
編寫您的檢視¶
每個檢視都負責做兩件事之一:返回一個包含請求頁面內容的 HttpResponse
物件,或引發一個例外,例如 Http404
。其餘的則取決於您。
通常,檢視會根據參數擷取資料、載入範本,並使用擷取的資料呈現範本。以下是上述 year_archive
的範例檢視
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
範本。以下是它的樣子
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.pub_date|date:"F j, Y" }}
使用 Unix 風格的「管線」(「|」字元)。這稱為範本篩選器,它是一種篩選變數值的方法。在這種情況下,日期篩選器會以給定的格式格式化 Python 日期時間物件(如 PHP 的 date 函數中所找到的)。
您可以鏈結任意多個篩選器。您可以編寫自訂範本篩選器。您可以編寫自訂範本標籤,這些標籤會在幕後執行自訂 Python 程式碼。
最後,Django 使用「範本繼承」的概念。{% extends "base.html" %}
的作用正是如此。它的意思是「首先載入名為 'base' 的範本,該範本已定義了一堆區塊,並使用以下區塊填滿這些區塊」。簡而言之,這可讓您大幅減少範本中的冗餘:每個範本都只需定義該範本獨有的內容。
以下是「base.html」範本的樣子,包括使用靜態檔案
templates/base.html
¶{% load static %}
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<img src="{% static 'images/sitelogo.png' %}" alt="Logo">
{% block content %}{% endblock %}
</body>
</html>
簡單來說,它定義了網站的外觀和風格(包含網站的標誌),並為子範本提供「孔」來填寫。這意味著可以透過變更單一檔案(基本範本)來完成網站重新設計。
它還能讓您建立網站的多個版本,使用不同的基礎樣板,同時重複使用子樣板。Django 的創建者們運用這項技術,僅透過建立新的基礎樣板,就製作出截然不同的網站行動版。
請注意,如果您偏好其他系統,您不必使用 Django 的樣板系統。雖然 Django 的樣板系統與 Django 的模型層整合得特別好,但沒有任何事情強迫您必須使用它。就這點而言,您也不必使用 Django 的資料庫 API。您可以使用其他資料庫抽象層、讀取 XML 檔案、讀取硬碟中的檔案,或是任何您想要的方式。Django 的每一部分(模型、視圖、樣板)都與下一部分解耦。
這只是冰山一角¶
這只是對 Django 功能的快速概述。還有一些更有用的功能: