概述
Django 無(wú)需數(shù)據(jù)庫(kù)就可以使用剩失,它提供了 對(duì)象關(guān)系映射器 通過(guò)此技術(shù)缤谎,你可以使用 Python 代碼來(lái)描述數(shù)據(jù)庫(kù)結(jié)構(gòu)。
你可以使用強(qiáng)大的 數(shù)據(jù)-模型語(yǔ)句 來(lái)描述你的數(shù)據(jù)模型篡撵,這解決了數(shù)年以來(lái)在數(shù)據(jù)庫(kù)模式中的難題判莉。以下是一個(gè)簡(jiǎn)明的例子:
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
應(yīng)用數(shù)據(jù)模型
接下來(lái),運(yùn)行Django命令行實(shí)用程序以自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)表:
$ python manage.py makemigrations
$ python manage.py migrate
該 makemigrations
命令查找所有可用的models育谬,為任意一個(gè)在數(shù)據(jù)庫(kù)中不存在對(duì)應(yīng)數(shù)據(jù)表的model創(chuàng)建 migrations 腳本文件券盅。migrate
命令則運(yùn)行這些 migrations 自動(dòng)創(chuàng)建數(shù)據(jù)庫(kù)表。還提供可選的 更豐富的控制模式膛檀。
享用便捷的 API
接下來(lái)锰镀,你就可以使用一套便捷而豐富的 Python API 訪問(wèn)你的數(shù)據(jù)。API是動(dòng)態(tài)創(chuàng)建的咖刃,不需要代碼生成:
# 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()
一個(gè)動(dòng)態(tài)管理接口:并非徒有其表
當(dāng)你的模型完成定義泳炉,Django 就會(huì)自動(dòng)生成一個(gè)專業(yè)的生產(chǎn)級(jí) 管理接口 ——一個(gè)允許認(rèn)證用戶添加、更改和刪除對(duì)象的 Web 站點(diǎn)僵缺。你只需在 admin 站點(diǎn)上注冊(cè)你的模型即可:
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)
from django.contrib import admin
from . import models
admin.site.register(models.Article)
這樣設(shè)計(jì)所遵循的理念是胡桃,站點(diǎn)編輯人員可以是你的員工踩叭、你的客戶磕潮、或者就是你自己——而你大概不會(huì)樂(lè)意去廢半天勁創(chuàng)建一個(gè)只有內(nèi)容管理功能的后臺(tái)管理界面。
創(chuàng)建 Django 應(yīng)用的典型流程是容贝,先建立數(shù)據(jù)模型自脯,然后搭建管理站點(diǎn),之后你的員工(或者客戶)就可以向網(wǎng)站里填充數(shù)據(jù)了斤富。后面我們會(huì)談到如何展示這些數(shù)據(jù)膏潮。
規(guī)劃 URLs
簡(jiǎn)潔優(yōu)雅的 URL 規(guī)劃對(duì)于一個(gè)高質(zhì)量 Web 應(yīng)用來(lái)說(shuō)至關(guān)重要。Django 推崇優(yōu)美的 URL 設(shè)計(jì)满力,所以不要把諸如 .php
和 .asp
之類的冗余的后綴放到 URL 里焕参。
為了設(shè)計(jì)你自己的 URLconf 轻纪,你需要?jiǎng)?chuàng)建一個(gè)叫做 URLconf 的 Python 模塊。這是網(wǎng)站的目錄叠纷,它包含了一張 URL 和 Python 回調(diào)函數(shù)之間的映射表刻帚。URLconf 也有利于將 Python 代碼與 URL 進(jìn)行解耦(譯注:使各個(gè)模塊分離,獨(dú)立)涩嚣。
下面這個(gè) URLconf 適用于前面 Reporter
/Article
的例子:
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 回調(diào)函數(shù)(“視圖”)崇众。路徑字符串使用參數(shù)標(biāo)簽從URL中“捕獲”相應(yīng)值。當(dāng)用戶請(qǐng)求頁(yè)面時(shí)航厚,Django 依次遍歷路徑味混,直至初次匹配到了請(qǐng)求的 URL膝昆。(如果無(wú)匹配項(xiàng),Django 會(huì)調(diào)用 404 視圖。) 這個(gè)過(guò)程非晨交瘢快,因?yàn)槁窂皆诩虞d時(shí)就編譯成了正則表達(dá)式夯接。
一旦有 URL 路徑匹配成功舌菜,Django 會(huì)調(diào)用相應(yīng)的視圖函數(shù)。每個(gè)視圖函數(shù)會(huì)接受一個(gè)請(qǐng)求對(duì)象——包含請(qǐng)求元信息——以及在匹配式中獲取的參數(shù)值澈蚌。
例如摹芙,當(dāng)用戶請(qǐng)求了這樣的 URL "/articles/2005/05/39323/",Django 會(huì)調(diào)用 news.views.article_detail(request, year=2005, month=5, pk=39323)宛瞄。
編寫(xiě)視圖
視圖函數(shù)的執(zhí)行結(jié)果只可能有兩種:返回一個(gè)包含請(qǐng)求頁(yè)面元素的 HttpResponse
對(duì)象浮禾,或者是拋出 Http404
這類異常。至于執(zhí)行過(guò)程中的其它的動(dòng)作則由你決定份汗。
通常來(lái)說(shuō)盈电,一個(gè)視圖的工作就是:從參數(shù)獲取數(shù)據(jù),裝載一個(gè)模板杯活,然后將根據(jù)獲取的數(shù)據(jù)對(duì)模板進(jìn)行渲染匆帚。下面是一個(gè) year_archive
的視圖樣例:
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)
這個(gè)例子使用了 Django 模板系統(tǒng) ,它有著很多強(qiáng)大的功能旁钧,而且使用起來(lái)足夠簡(jiǎn)單吸重,即使不是程序員也可輕松使用。
設(shè)計(jì)模板
上面的代碼加載了 news/year_archive.html
模板歪今。
Django 允許設(shè)置搜索模板路徑嚎幸,這樣可以最小化模板之間的冗余。在 Django 設(shè)置中寄猩,你可以通過(guò) DIRS
參數(shù)指定一個(gè)路徑列表用于檢索模板嫉晶。如果第一個(gè)路徑中不包含任何模板,就繼續(xù)檢查第二個(gè),以此類推替废。
讓我們假設(shè) news/year_archive.html
模板已經(jīng)找到箍铭。它看起來(lái)可能是下面這個(gè)樣子:
{% 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 %}
我們看到變量都被雙大括號(hào)括起來(lái)了。 {{ article.headline }}
的意思是“輸出 article 的 headline 屬性值”椎镣。這個(gè)“點(diǎn)”還有更多的用途坡疼,比如查找字典鍵值、查找索引和函數(shù)調(diào)用衣陶。
我們注意到 {{ article.pub_date|date:"F j, Y" }}
使用了 Unix 風(fēng)格的“管道符”(“|”字符)柄瑰。這是一個(gè)模板過(guò)濾器,用于過(guò)濾變量值剪况。在這里過(guò)濾器將一個(gè) Python datetime 對(duì)象轉(zhuǎn)化為指定的格式(就像 PHP 中的日期函數(shù)那樣)教沾。
你可以將多個(gè)過(guò)濾器連在一起使用。你還可以使用你 自定義的模板過(guò)濾器 译断。你甚至可以自己編寫(xiě) 自定義的模板標(biāo)簽 授翻,相關(guān)的 Python 代碼會(huì)在使用標(biāo)簽時(shí)在后臺(tái)運(yùn)行。
Django 使用了 ''模板繼承'' 的概念孙咪。這就是 {% extends "base.html" %}
的作用堪唐。它的含義是''先加載名為 base 的模板,并且用下面的標(biāo)記塊對(duì)模板中定義的標(biāo)記塊進(jìn)行填充''翎蹈。簡(jiǎn)而言之淮菠,模板繼承可以使模板間的冗余內(nèi)容最小化:每個(gè)模板只需包含與其它文檔有區(qū)別的內(nèi)容。
下面是 base.html 可能的樣子荤堪,它使用了 靜態(tài)文件 :
{% load static %}
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<img src="{% static 'images/sitelogo.png' %}" alt="Logo">
{% block content %}{% endblock %}
</body>
</html>
簡(jiǎn)而言之合陵,它定義了這個(gè)網(wǎng)站的外觀(利用網(wǎng)站的 logo),并且給子模板們挖好了可以填的”坑“澄阳。這就意味著你可以通過(guò)修改基礎(chǔ)模板以達(dá)到重新設(shè)計(jì)網(wǎng)頁(yè)的目的拥知。
它還可以讓你利用不同的基礎(chǔ)模板并重用子模板創(chuàng)建一個(gè)網(wǎng)站的多個(gè)版本。通過(guò)創(chuàng)建不同的基礎(chǔ)模板碎赢,Django 的創(chuàng)建者已經(jīng)利用這一技術(shù)來(lái)創(chuàng)造了明顯不同的手機(jī)版本的網(wǎng)頁(yè)低剔。
注意,你并不是非得使用 Django 的模板系統(tǒng)肮塞,你可以使用其它你喜歡的模板系統(tǒng)襟齿。盡管 Django 的模板系統(tǒng)與其模型層能夠集成得很好,但這不意味著你必須使用它峦嗤。同樣蕊唐,你可以不使用 Django 的數(shù)據(jù)庫(kù) API。你可以用其他的數(shù)據(jù)庫(kù)抽象層烁设,像是直接讀取 XML 文件,亦或直接讀取磁盤文件,你可以使用任何方式装黑。Django 的任何組成——模型副瀑、視圖和模板——都是獨(dú)立的。
這僅是基本入門知識(shí)
以上只是 Django 的功能性概述恋谭。Django 還有更多實(shí)用的特性:
- 緩存框架 可以與 memcached 或其它后端集成糠睡。
- 聚合器框架 可以通過(guò)編寫(xiě)一個(gè)小型 Python 類來(lái)創(chuàng)建 RRS 和 Atom摘要。
- 功能豐富的自動(dòng)生成的后臺(tái)——這份概要只是簡(jiǎn)單介紹了下疚颊。
接下來(lái)您可以 下載 Django 狈孔,閱讀 實(shí)例教程。
訪問(wèn)流程
Browser => urls => views => templates => models => DB