前后端分離概述
前端(英語:front-end)和后端(英語:back-end)是描述進程開始和結(jié)束的通用詞匯。前端作用于采集輸入信息,后端進行處理。計算機程序的界面樣式,視覺呈現(xiàn)屬于前端。在軟體架構(gòu)和程序設(shè)計領(lǐng)域,前端是軟體系統(tǒng)中直接和用戶交互的部分,而后端控制著軟件的輸出。將軟體分為前端和后端是一種將軟體的不同的功能部分相互分離的抽象的劃分方式。
在傳統(tǒng)的Web應(yīng)用開發(fā)中,大多數(shù)的程序員會將瀏覽器作為前后端的分界線。將瀏覽器中為用戶進行頁面展示的部分稱之為前端,而將運行在服務(wù)器,為前端提供業(yè)務(wù)邏輯和數(shù)據(jù)準(zhǔn)備的所有代碼統(tǒng)稱為后端。
相較于使用MVC框架,前后端開發(fā)未能分離的時期,前后端分離的開發(fā)具有很多的優(yōu)勢:
能夠有效地實現(xiàn)前后端代碼的解耦合,前后端的開發(fā)變得相對獨立,且不會出現(xiàn)之前那樣相互制約的情況,這為前后端工程師的開發(fā)工作提供了極大的便利,開發(fā)工作變得更加簡單和高效。
代碼的更新和維護變得更加簡單,在前后端代碼未能實現(xiàn)較好的解耦合的時期,在對代碼進行更新和維護的時候常常會出現(xiàn)牽一發(fā)而動全身的現(xiàn)象,而前后端分離的開發(fā)則有效地規(guī)避了這種現(xiàn)象。
可擴展和可移植性更強,為以后的大型分布式架構(gòu)、彈性計算架構(gòu)、微服務(wù)架構(gòu)、多端化服務(wù)(多種客戶端,例如:瀏覽器,車載終端,安卓,IOS等等)打下堅實的基礎(chǔ)。
前后端開發(fā)的核心思想就是:前端HTML頁面通過AJAX調(diào)用后端的RESTFUL API接口并使用JSON數(shù)據(jù)進行交互。
后端
誠如上文中提到的那樣,在前后端分離的開發(fā)模式下,后端的工作主要是為前端提供數(shù)據(jù)接口,而這些接口提供的通常是JSON格式的數(shù)據(jù)。
在Django的框架下,我們可以利用它自帶的函數(shù)JsonResponse向瀏覽器返回Json格式的數(shù)據(jù)
def show_subjects(request):
queryset = Subject.objects.all()
subjects = []
for subject in queryset:
subjects.append({
'no': subject.no,
'name': subject.name,
'intro': subject.intro,
'isHot': subject.is_hot
})
return JsonResponse(subjects, safe=False)
"""
這里需要注意,JsonResponse默認(rèn)是將列表序列化成json格式的數(shù)據(jù),當(dāng)我們希望對
字典對象進行序列化時,必須指定參數(shù)safe為False,否則會出現(xiàn)TypeError的錯誤
"""
通過上述示例我們可以發(fā)現(xiàn),在使用JsonResponse對數(shù)據(jù)進行序列化之前,我們需要先手動將queryset查詢集對象轉(zhuǎn)換為列表或者字典,那有沒有什么方法或者工具能幫我們自動完成這個過程呢?
在Django中,我們可以使用第三方庫bpmappers來協(xié)助我們將queryset查詢集轉(zhuǎn)換成字典或者列表,有了這個工具,我們就可以改寫上面的代碼了。
安裝bpmappers
pip install bpmappers
編寫映射器
我們可以在應(yīng)用目錄下新建一個名為“mappers.py”的py文件來配置映射器
from bpmappers.djangomodel import ModelMapper
這里要導(dǎo)入ModelMapper和我們創(chuàng)建的Subject模型
from poll.models import Subject
class SubjectMapper(ModelMapper):
class Meta:
model = Subject
指定映射器要映射的模型
編寫好映射器之后我們就可以對我們的視圖函數(shù)進行改寫了
def show_subjects(request):
queryset = Subject.objects.all()
subjects = []
for subject in queryset:
subjects.append(SubjectMapper(subject).as_dict())
return JsonResponse(subjects, safe=False)
如上述代碼所示,我們在mappers.py中創(chuàng)建的映射器會幫助我們將queryset查詢集中的對象轉(zhuǎn)換成字典,之后我們再將這些字典數(shù)據(jù)放到列表中,最后利用JsonResponse進行序列化。這樣的方式在針對有很多字段的復(fù)雜的表的時候,其效率遠遠高于手動轉(zhuǎn)換。
上述的這些通過在視圖里使用函數(shù)來處理前端請求的方式我們把它稱為FBV,即基于函數(shù)的視圖。
然而,Python是一個面向?qū)ο蟮木幊陶Z言,如果只用函數(shù)來開發(fā),有很多面向?qū)ο蟮膬?yōu)點就錯失了(繼承、封裝、多態(tài))。所以Django在后來加入了CBV??梢宰屛覀冇妙悓懸晥D。這樣做的優(yōu)點主要下面兩種:
提高了代碼的復(fù)用性,可以使用面向?qū)ο蟮募夹g(shù),比如Mixin(多繼承)
可以用不同的函數(shù)針對不同的HTTP方法處理,而不是通過很多if判斷,提高代碼可讀性
DRF-Django REST framework
在Django框架中,我們可以使用第三方庫djangorestframework
pip install djangorestframework
在安裝了第三方庫djangorestframework之后,我們可以在項目目錄下創(chuàng)建一個名為“serializers.py”的py文件
然后在這個文件中創(chuàng)建序列化所需要的類
from rest_framework import serializers
from poll.models import Subject
class SubjectSerializer(serializers.ModelSerializer):
class Meta:
model = Subject
fields = ('no', 'name', 'intro', 'isHot')
然后我們再次對視圖進行改寫
from rest_framework.viewsets import ModelViewSet
from poll.serializers import SubjectSerializer
class SubjectView(ModelViewSet):
queryset = Subject.objects.all()
serializer_class = SubjectSerializer
最后我們在urls中配置路徑
from poll.views import SubjectView
urlpatterns = [
path('subjects/', SubjectView.as_view()),
]
完成上述步驟之后我們就可以獲得數(shù)據(jù)接口了。