橡皮擦,一個(gè)逗趣的互聯(lián)網(wǎng)高級(jí)網(wǎng)蟲。新的系列,讓我們一起進(jìn)入 Django 世界。
已經(jīng)完成的文章
- 滾雪球?qū)W Python 第三輪,Python Web 之 Django 的世界
- 小手哆嗦一下,就能用 Python Django 實(shí)現(xiàn)一個(gè)微型博客系統(tǒng)
- Django 做個(gè)小后臺(tái),細(xì)節(jié)在完善一點(diǎn)點(diǎn),滾雪球?qū)W Python 第三階段
- Django QuerySet 就學(xué)那么一點(diǎn)點(diǎn),一點(diǎn)點(diǎn)就夠了
五、Python Django 視圖
5.1 視圖返回 JSON 數(shù)據(jù)
在真實(shí)工作中 ,Python Web 工程師會(huì)向前端工程師反饋接口數(shù)據(jù),接口一般稱為 API,常見(jiàn)返回?cái)?shù)據(jù)的格式是 XML 或者 JSON,接下來(lái),就以最常見(jiàn)的 JSON 格式數(shù)據(jù)為案例,為你詳細(xì)說(shuō)明,Django 中是如何從數(shù)據(jù)庫(kù)向前臺(tái)發(fā)送數(shù)據(jù)的。
修改 views.py 文件。
from django.shortcuts import render
# 導(dǎo)入 JSON 格式數(shù)據(jù)響應(yīng)類
from django.http import JsonResponse
from .models import Blog
# Create your views here.
def blog_list(request):
blogs = Blog.objects.all()
# 用列表生成器生成一個(gè)對(duì)象
context = {
"data": [{"id": blog.id, "title": blog.title} for blog in blogs]
}
return JsonResponse(context)
在該文件頭部導(dǎo)入 models 中的 Blog 類,然后在通過(guò)新增加一個(gè) blog_list 函數(shù)返回 JsonResponse 對(duì)象。
5.2 創(chuàng)建路由
路由相關(guān)資料后續(xù)會(huì)進(jìn)行補(bǔ)充,本篇博客只需要掌握到通過(guò)不同 URL 返回不同數(shù)據(jù)即可。
在 blog 文件夾中創(chuàng)建一個(gè)新的文件 urls.py,代碼內(nèi)容如下:
from django.urls import path
import blog.views as blog_views
urlpatterns = [
path('list/', blog_views.blog_list)
]
該文件代碼編寫完畢,還需要修改 my_website 文件夾中的 urls.py 文件,修改部分如下:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('blog/', include('blog.urls')),
path('admin/', admin.site.urls),
]
此時(shí)你的項(xiàng)目文件結(jié)構(gòu)如下圖所示,重點(diǎn)注意 urls.py 文件出現(xiàn)了兩次。

通過(guò)下述命令運(yùn)行現(xiàn)在的應(yīng)用程序:
python manage.py runserver
直接訪問(wèn) http://127.0.0.1:8000/ 會(huì)出如下錯(cuò)誤,要求必須訪問(wèn)一個(gè)目錄。輸入 http://127.0.0.1:8000/admin 訪問(wèn)之前博客涉及的后臺(tái),輸入 http://127.0.0.1:8000/blog/list/ 得到 JSON 格式的數(shù)據(jù)。

JSON 格式數(shù)據(jù)如下,中文被進(jìn)行了 UNICODE 編碼

同樣可以直接通過(guò)開發(fā)者工具進(jìn)行查詢,點(diǎn)擊下圖藍(lán)色矩形區(qū)域即可。

應(yīng)用完成之后,就可以進(jìn)行復(fù)盤學(xué)習(xí)了。
通過(guò) URL 地址進(jìn)行訪問(wèn),如果訪問(wèn)的地址是 /blog,Django 會(huì)自動(dòng)加載 urls.py 中的配置,即下述代碼:
urlpatterns = [
path('blog/', include('blog.urls')),
path('admin/', admin.site.urls),
]
發(fā)現(xiàn)匹配到 url 中的 blog/,然后加載 blog.urls 文件,對(duì)應(yīng)文件代碼如下:
from django.urls import path
import blog.views as blog_views
urlpatterns = [
path('list/', blog_views.blog_list)
]
這里包含了一個(gè) list/ 匹配器,所以通過(guò) blog/list/ 調(diào)用了視圖中 blog_view.blog_list 函數(shù),該函數(shù)用于返回 JSON 格式的數(shù)據(jù)。注意 blog_view 是導(dǎo)入的 view 模塊進(jìn)行重命名得來(lái),代碼在頭部 import blog.views as blog_views。
def blog_list(request):
blogs = Blog.objects.all()
# 用列表生成器生成一個(gè)對(duì)象
context = {
"data": [{"id": blog.id, "title": blog.title} for blog in blogs]
}
return JsonResponse(context)
先理解邏輯關(guān)系,后續(xù)在補(bǔ)充專業(yè)的語(yǔ)法定義。
5.3 擴(kuò)展詳情頁(yè)
有了上文的邏輯關(guān)系之后,在實(shí)現(xiàn)一個(gè)返回單條博客數(shù)據(jù)的接口,首先編輯 views.py 文件。
def detail(request, blog_id):
blog = Blog.objects.get(id=blog_id)
blog = {
"id": blog.id,
"title": blog.title,
"content": blog.content,
"create_time": blog.create_time
}
return JsonResponse(blog)
擴(kuò)展詳情頁(yè),發(fā)現(xiàn)一個(gè)單詞拼寫錯(cuò)誤,修改 create_time 之后,注意使用如下命令對(duì) sqlite 進(jìn)行重新生成。
> python manage.py makemigrations blog
Did you rename blog.creatr_time to blog.create_time (a DateField)? [y/N] y
Migrations for 'blog':
blog\migrations\0002_auto_20210329_0940.py
- Rename field creatr_time on blog to create_time
該命令運(yùn)行完,再運(yùn)行下述命令:
>python manage.py migrate blog
Operations to perform:
Apply all migrations: blog
Running migrations:
Applying blog.0002_auto_20210329_0940... OK
繼續(xù)修改 blog 文件夾中的 urls.py 文件,代碼如下:
from django.urls import path
import blog.views as blog_views
urlpatterns = [
path('list/', blog_views.blog_list),
path('detail/<int:blog_id>', blog_views.detail)
]
編寫完畢以上代碼之后,就可以通過(guò) http://127.0.0.1:8000/blog/detail/1 進(jìn)行單條博客數(shù)據(jù)獲取,地址 URL 的格式為 http://127.0.0.1:8000/blog/detail/{整數(shù)序號(hào)}。
在地址中輸入整數(shù)序號(hào),可以被后臺(tái)的 blog_id 獲取到,而 blog_id 將會(huì)傳遞到 detail 方法中。
上述代碼還有一個(gè)需要特別說(shuō)明一下 <int:blog_id> 前面的 int 被稱作路徑轉(zhuǎn)換器,常見(jiàn)的路徑轉(zhuǎn)換器有如下內(nèi)容:
-
str:匹配任何非空字符串,默認(rèn)值; -
int:匹配零或正整數(shù); -
uuid:匹配一種特定類型的字符串格式; -
path:匹配任何非空字符,可以匹配路徑地址,包括/。
后面的博客對(duì)上述內(nèi)容都會(huì)有所涉及,先應(yīng)用起來(lái)為主,畢竟?jié)L雪球系列是一個(gè)反復(fù)學(xué)習(xí)的專欄。
5.4 分頁(yè)實(shí)現(xiàn)
接下來(lái)繼續(xù)對(duì) blog_list 方法進(jìn)行擴(kuò)展,讓其實(shí)現(xiàn)分頁(yè)操作。重點(diǎn)對(duì) views.py 中的 blog_list(request) 方法進(jìn)行改造,核心代碼參考下述內(nèi)容。
from django.shortcuts import render
# 導(dǎo)入 JSON 格式數(shù)據(jù)響應(yīng)類
from django.http import JsonResponse
# 導(dǎo)入分頁(yè)組件
from django.core.paginator import Paginator
from .models import Blog
# Create your views here.
def blog_list(request):
# blogs = Blog.objects.all()
# # 用列表生成器生成一個(gè)對(duì)象
# context = {
# "data": [{"id": blog.id, "title": blog.title} for blog in blogs]
# }
# 頁(yè)碼默認(rèn)獲取 page 參數(shù),默認(rèn)值為 1
page = request.GET.get("page", 1)
# 默認(rèn)每頁(yè) 20 條數(shù)據(jù)
page_size = request.GET.get("page_size", 20)
# 獲取全部數(shù)據(jù)
blog_all = Blog.objects.all()
# 分頁(yè)對(duì)象
paginator = Paginator(blog_all, page_size)
# 當(dāng)前頁(yè)碼
current_page = paginator.get_page(page)
blogs = current_page.object_list
context = {
"blog_list": [{"id": blog.id, "title": blog.title} for blog in blogs],
"paginator": {
"total_count": paginator.count,
"num_pages": paginator.num_pages,
"page_size": paginator.per_page,
"page_number": current_page.number
}
}
return JsonResponse(context)
在代碼頂部導(dǎo)入 from django.core.paginator import Paginator 分頁(yè)模塊,用于后續(xù)的分頁(yè)內(nèi)容,數(shù)據(jù)通過(guò) Blog.objects.all() 方法提前獲取,該方式存在效率問(wèn)題,后續(xù)學(xué)習(xí)到進(jìn)階內(nèi)容,將會(huì)對(duì)本部分進(jìn)行修改。
編寫完畢,通過(guò) URL 相關(guān)參數(shù)即可實(shí)現(xiàn)分頁(yè)效果。訪問(wèn) http://127.0.0.1:8000/blog/list/?page=1&page_size=1 得到的效果如下:

5.5 這篇博客的總結(jié)
本篇博客重點(diǎn)學(xué)習(xí)了 Django 中的視圖,本文是基于函數(shù)的視圖(FBV),在以后的博客中,我們將學(xué)習(xí)基于類的視圖(CBV),在實(shí)際的開發(fā)中基于類視圖應(yīng)用比較廣泛,使用 Django 開發(fā) API 也有成熟的框架借鑒,例如 Django Rest Framework。
相關(guān)閱讀
- Python 爬蟲 100 例教程,超棒的爬蟲教程,立即訂閱吧
- Python 游戲世界(更新中,目標(biāo)文章數(shù) 50+,現(xiàn)在訂閱,都是老粉)
- Python 爬蟲小課,精彩 9 講
今天是持續(xù)寫作的第 <font color="red">122</font> / 200 天。
如果你想跟博主建立親密關(guān)系,可以關(guān)注同名公眾號(hào) <font color="red">夢(mèng)想橡皮擦</font>,近距離接觸一個(gè)逗趣的互聯(lián)網(wǎng)高級(jí)網(wǎng)蟲。
博主 ID:夢(mèng)想橡皮擦,希望大家<font color="red">點(diǎn)贊</font>、<font color="red">評(píng)論</font>、<font color="red">收藏</font>。
<font color=white size=1>
django微信小程序商城 Django 教程 2020年php涼透了
django和spring比較 django開源項(xiàng)目 為什么大公司很少用vue
python的django框架 django怎么安裝 django企業(yè)開發(fā)實(shí)戰(zhàn)pdf
</font>