1. 程式人生 > >Django匆匆一眼卻解答了多年疑惑

Django匆匆一眼卻解答了多年疑惑

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 是資料模型,定義了資料庫的表和欄位。 例如: ```python 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 遷移到資料庫中: ```shell $ python manage.py makemigrations $ python manage.py migrate ``` 執行完成後,就會在資料庫中按照 model 定義的表名、欄位名、約束條件等,建立表結構。 # 資料操作 接著就可以在程式中寫程式碼操作資料了。為了直觀看到結果,這裡以命令列形式進行演示: ```shell # 匯入已建立的 models >>> from news.models import Article, Reporter # 查詢表 Reporter 為空 >>> Reporter.objects.all() # 例項化物件,建立 1 條資料,表 Reporter 的欄位是 full_name >>> r = Reporter(full_name='John Smith') # 必須顯式呼叫 save() 函式,才會真正寫資料到資料庫 >>> r.save() # 儲存後就有 id 了 >>> r.id 1 # 查詢表 Reporter 有資料了 >>> Reporter.objects.all() ]> # 訪問物件屬性 >>> r.full_name 'John Smith' # Django 提供了 get() 函式來支援更多查詢方式 >>> Reporter.objects.get(id=1) >>> Reporter.objects.get(full_name__startswith='John') >>> Reporter.objects.get(full_name__contains='mith') >>> 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() # a.reporter 可以賦值給 r >>> r = a.reporter >>> r.full_name 'John Smith' # r 也可以訪問 Article >>> r.article_set.all() # 可以藉助 filter() 函式按條件過濾資料 >>> Article.objects.filter(reporter__full_name__startswith='John') # 賦值後呼叫 save() 函式更新資料 >>> r.full_name = 'Billy Goat' >>> r.save() # 使用 delete() 函式刪除物件,資料庫這條資料也會被刪除 >>> r.delete() ``` # 自帶 Admin 後臺 一般不會用它。 # 設計 URLs 我們是通過 URL 傳送請求的,服務端程式做處理,處理的函式叫做回撥函式。Django 在 urls.py 檔案中編寫 URL 和回撥函式的對映關係。例如: ```python from django.urls import path from . import views urlpatterns = [ path('articles//', views.year_archive), path('articles///', views.month_archive), path('articles////', views.article_detail), ] ``` `path()` 的第一引數是 URL,這裡使用了 `<>` 引數標籤來獲取 URL 中的資料,然後傳入到回撥函式中。第二個引數是回撥函式,位於 views 中。 如果請求 URL “/articles/2005/05/39323/”,Django 就會獲取引數值後呼叫回撥函式: ```python news.views.article_detail(request, year=2005, month=5, pk=39323) ``` Django 在啟動載入時就會把這些 path 編譯為正則表示式,查詢速度飛快。匹配到第一個後就會停止查詢,呼叫回撥函式。如果找完了都沒有,就會呼叫 404 這個特殊 view,表示沒找到。 # 編寫 views 在 views 中編寫回調函式。每個回撥函式只做 1 件事,要麼返回包含響應的 ` HttpResponse` 物件,要麼丟擲異常,如 `Http404` 。例如: ```python 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 這一套是這麼一回事。 參考資料: https://docs.djangoproject.com/en/3.1/intro/o