Django 是 Python 的 一款 Web 開發框架,另外還有 Tornado,Flask,Twisted。為什么我要選擇學 Django?原因很簡單,上家公司來了個網易的測開,就是用 Django 開發的測試平台。
這位測開沒多久就離職去騰訊了,我啥也沒學到,看了他的代碼,很多是寫的 Vue 代碼,哭啊。
Django 誕生於 2003 年的秋天,由 Lawrence Journal-World 報紙的程序員 Adrian Holovaty 和 Simon Willison 編寫而成。新聞編輯室的開發節奏是非常快的,正因如此,Django 相比於其他框架的特點就是短、平、快。這也符合 Python 的風格。時至今日,Django 已經發展到了 3.1.3 版本。本系列將基於這一版本的官方文檔,邊學習邊實踐,整理成文,分享給大家。
Django 系列不是教程,而是學習筆記、心得體會、踩坑記錄,內容編排上可能會有點亂。需要看教程請閱讀官方文檔,水平有限,實在抱歉。
Django 遵循 MVC 架構模式,所以接下來就看看如何使用 Django 完成 Web 開發。特別注意,本文的內容不具有實操性,看看即可。
定義 model
model 是數據模型,定義了數據庫的表和字段。
例如:
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
通過類和屬性,分別定義了 2 張表 Reporter 和 Article,以及它們的字段(Reporter 1 個字段,Article 4 個字段)。
這其實就是 ORM,即 Object Relational Mapping,對象關系映射,把程序代碼中的對象映射到關系型數據庫中,不用寫 SQL,就可以直接操作數據了。ORM 實現了數據持久化。我們都知道程序是運行在內存中的,跑完就沒了。為了把數據保存下來,就需要使用 ORM 技術把內存中的數據(程序對象)存到關系型數據庫中,進而轉移到磁盤上。Django 自帶了一個 ORM,開箱即用。
數據遷移
使用 2 條命令,就可以把 model 遷移到數據庫中:
$ python manage.py makemigrations
$ python manage.py migrate
執行完成后,就會在數據庫中按照 model 定義的表名、字段名、約束條件等,創建表結構。
數據操作
接着就可以在程序中寫代碼操作數據了。為了直觀看到結果,這里以命令行形式進行演示:
# 導入已創建的 models
>>> from news.models import Article, Reporter
# 查詢表 Reporter 為空
>>> Reporter.objects.all()
<QuerySet []>
# 實例化對象,創建 1 條數據,表 Reporter 的字段是 full_name
>>> r = Reporter(full_name='John Smith')
# 必須顯式調用 save() 函數,才會真正寫數據到數據庫
>>> r.save()
# 保存后就有 id 了
>>> r.id
1
# 查詢表 Reporter 有數據了
>>> Reporter.objects.all()
<QuerySet [<Reporter: John Smith>]>
# 訪問對象屬性
>>> r.full_name
'John Smith'
# Django 提供了 get() 函數來支持更多查詢方式
>>> 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.
# 給表 Article 添加 1 條數據
# 有 4 個字段 pub_date, headline, content, reporter
# reporter=r,用 Reporter 對象賦值
>>> from datetime import date
>>> a = Article(pub_date=date.today(), headline='Django is cool',
... content='Yeah.', reporter=r)
>>> a.save()
# 表 Article 也有數據了
>>> Article.objects.all()
<QuerySet [<Article: Django is cool>]>
# a.reporter 可以賦值給 r
>>> r = a.reporter
>>> r.full_name
'John Smith'
# r 也可以訪問 Article
>>> r.article_set.all()
<QuerySet [<Article: Django is cool>]>
# 可以借助 filter() 函數按條件過濾數據
>>> Article.objects.filter(reporter__full_name__startswith='John')
<QuerySet [<Article: Django is cool>]>
# 賦值后調用 save() 函數更新數據
>>> r.full_name = 'Billy Goat'
>>> r.save()
# 使用 delete() 函數刪除對象,數據庫這條數據也會被刪除
>>> r.delete()
自帶 Admin 后台
一般不會用它。
設計 URLs
我們是通過 URL 發送請求的,服務端程序做處理,處理的函數叫做回調函數。Django 在 urls.py 文件中編寫 URL 和回調函數的映射關系。例如:
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),
]
path()
的第一參數是 URL,這里使用了 <>
參數標簽來獲取 URL 中的數據,然后傳入到回調函數中。第二個參數是回調函數,位於 views 中。
如果請求 URL “/articles/2005/05/39323/”,Django 就會獲取參數值后調用回調函數:
news.views.article_detail(request, year=2005, month=5, pk=39323)
Django 在啟動加載時就會把這些 path 編譯為正則表達式,查找速度飛快。匹配到第一個后就會停止查找,調用回調函數。如果找完了都沒有,就會調用 404 這個特殊 view,表示沒找到。
編寫 views
在 views 中編寫回調函數。每個回調函數只做 1 件事,要么返回包含響應的 HttpResponse
對象,要么拋出異常,如 Http404
。例如:
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)
return render() 函數會返回一個 HttpResponse
對象。
注意,這個例子用到的是 Django 自帶的模板引擎。所謂模板引擎,就是前端的 HTML 模板,里面的數據可以寫成變量,從后端動態獲取。除了內置的這個,還有其他模板引擎如 Thymeleaf、FreeMarker 等。不過這些使用都很少了。現在流行前后端分離,后端不需要寫 HTML,只提供 RESTful 接口就可以了。說到 RESTful,就不得不提另外一個 Django 的衍生框架 DRF(Django REST Framework)。一步一步來,先學好了 Django,才能更好理解 DRF。
內置模板引擎
暫時不做介紹。
小結
本文以 Web 后台為例,講解了從 model,到 ORM,到數據操作,到 URL 映射,到 views 回調函數的編寫鏈路。實際操作會復雜得多。以前學其他框架有點懵,寫這篇文章,倒是讓我明白了 MVC 這一套是這么一回事。
參考資料: