看完這篇博客,Python Django 你就學(xué)會(huì)一半了

橡皮擦,一個(gè)逗趣的互聯(lián)網(wǎng)高級(jí)網(wǎng)蟲。新的系列,讓我們一起進(jìn)入 Django 世界。

已經(jīng)完成的文章

五、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)了兩次。

20210329091911450[1].png

通過(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ù)。

20210329092108712[1].png

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

20210329092306460[1].png

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

20210329092456588[1].png

應(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 得到的效果如下:

20210329175424822[1].png

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)閱讀

  1. Python 爬蟲 100 例教程,超棒的爬蟲教程,立即訂閱吧
  2. Python 游戲世界(更新中,目標(biāo)文章數(shù) 50+,現(xiàn)在訂閱,都是老粉)
  3. 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>

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容