關於RESTful的問題,在最近的面試中遇到不少,以前有過必定的瞭解,但沒有系統性的總結分析。因此如今結合Django RESTframework來加深對RESTful的理解,同時梳理這過程的一些知識點。html
這個問題是最容易想到的,首先要分析這個問題,網上的其餘文章都會講到有關REST(Representational State Transfer),中文翻譯:」表述性狀態傳遞「,再白話一點就是對資源的表述性狀態傳遞。剛開始,看到這裏頭都大了,那咱們來看看其中比較關鍵須要瞭解到的知識點。前端
這裏的資源指的是網絡上的每個實體,而每個實體都有着對應的URI(統一資源標識符),若是須要訪問這個資源,能夠經過訪問它的URI便可。python
簡單來講就是資源的表現形式,好比圖片、HTML、文本等等。面試
客戶端能夠經過GET、POST、PUT、DELETE HTTP動詞來操做資源。數據庫
REST從資源的角度來審視整個網絡,將分佈再網絡中某個結點經過URI進行標識,而客戶端和服務端傳遞的是資源的某種表現層,而且客戶端經過HTTP動詞,對服務器資源操做,實現」表述性狀態轉化「。(表述性:客戶端請求一個資源,而且經過服務器拿到資源)
知足以上這些約束條件和原則的應用程序或設計就是RESTful。換言之RESTful就是一種架構的規範和約束。django
對API的設計來說,RESTful是現在常見的的設計規範,一般用於Web數據接口的設計。這裏講講從網上大體總結的幾個RESTful API的設計細節。json
客戶端使用」動詞+賓語"的結構操做服務器資源,動詞指的是HTTP動詞,賓語指的是資源。HTTP動詞對應的服務器資源操做:後端
- GET(SELECT):從服務器取出資源(一項或多項)。
- POST(CREATE):在服務器新建一個資源。
- PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源)。
- PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
- DELETE(DELETE):從服務器刪除資源。
因爲賓語是API中的URI,是HTTP動詞做用的的對象,應該是名詞,而不是動詞。api
對於URI建議使用複數服務器
客戶端的每一次請求,服務器給出迴應,而回應包括HTTP狀態碼和數據兩部分。
HTTP狀態碼的含義:
- 1xx:相關信息
- 2xx:操做成功
- 3xx:重定向
- 4xx:客戶端錯誤
- 5xx:服務器錯誤
API返回的數據格式,不該該是一個純文本,應該是一個JSON對象,這樣才符合結構化流程。一樣服務器迴應的HTTP頭的Content-Type屬性一樣要設置爲application/json。
在發生錯誤的時候,不該該返回一個200狀態碼,而後把錯誤信息放在數據體裏,由於這樣會致使須要解析完數據體才能知道操做失敗。
Django RestFramework是一個基於Django上構建符合RESTful風格Web api,而且自身還帶有測試的頁面,方便測試本身的API,因此對於」先後端分離「的開發模式來說十分合適。
先後端分離指的是後端來講只須要提供數據接口,再也不渲染模板,前端只須要獲取數據而且呈現。這樣的有許多優勢:
- 先後端解耦,接口複用,減小開發量
- 各司其職,先後端同步開發,提高工做效率,定好接口規範
- 更利於調試、測試和運維
Rest Framework基本組件:
- APIView
- 解析器組件:對請求的數據進行解析,根據不一樣請求題進行解析
- 序列化組件:相似於Django的Form,能夠經過自定義操做得到想要的數據形式
- 視圖類(mixin)
- 認證組件
- 權限組件
- 頻率組件
- 分頁組件
- 響應器組件
- url註冊器
關於Django的視圖函數,能夠基於FBV模式也能夠基於CBV模式:
- FBV模式:Django的路由映射表裏進行url和視圖函數的關聯
- CBV模式:而CBV模式則是在views.py中定義視圖類,在視圖類中視圖函數,如(get,post,put,delete)等
Django RESTFramework就是基於CBV模式,當一個http請求到達Django後,首先執行中間件的方法,而後在進行路由匹配。
當路由匹配後,會執行自定義類中的as_view()方法,若是不存在則會調用父類的as_view()方法,最後再調用到dispatch()方法處理不一樣request請求,執行不一樣的方法。(這段過程當中設計到Django CBV模式的處理流程,以及一些源碼知識)
安裝Django restframework:
pip install djangorestframework
新建項目,新建應用,修改settings.py
django-admin startproject Crawl cd Crawl python manage.py startapp music
settings.py(將rest_framework新增到INSTALLED_APPS)
(其他的修改數據庫配置、修改語言、時區就不一一列出來)
項目文件樹:
設計一個有關於存儲歌曲的詳細信息表(music/models.py):
from django.db import models class Music(models.Model): music_author = models.CharField(max_length=50, verbose_name='歌唱者') music_name = models.CharField(max_length=100, verbose_name='歌曲名') music_album = models.CharField(max_length=100, verbose_name='專輯') music_time = models.CharField(max_length=10, verbose_name='歌曲時間') music_type = models.CharField( max_length=100, null=True, verbose_name='歌曲類型', default=None) music_lyrics = models.CharField( max_length=100, blank=True, verbose_name='做詞者') music_arranger = models.CharField( max_length=100, blank=True, verbose_name='做曲者')
同步數據庫:
python manage.py makemigrations python manage.py migrate
建立一個序列化Serialier類,提供序列化和反序列化的途徑,使之能夠轉化爲如json的表現形式,相似於Django的Form表單的原理。在music目錄下,建立serializers.py:
from rest_framework import serializers from music.models import * class MusicSerializer(serializers.ModelSerializer): class Meta: fields = '__all__' model = Music
經過前面提到的CBV模式,設計視圖處理函數和路由映射:
Crawl/urls.py
from django.contrib import admin from django.urls import path, include import music urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('music.urls')), ]
music/urls.py
from django.urls import path from music.views import * urlpatterns = [ path('', MusicList.as_view()), path('<int:pk>/', MusicDetail.as_view()), ]
music/views.py
from django.shortcuts import render from rest_framework import generics from rest_framework.views import APIView from rest_framework.response import Response from music.models import * from music.serializers import MusicSerializer # Create your views here. class MusicList(APIView): def get(self, request): queryset = Music.objects.all() ret = MusicSerializer(queryset, many=True) return Response(ret.data) def post(self, request): music = MusicSerializer(data=request.data) if music.is_valid(): music.save() return Response(music.data) else: return Response(music.errors) class MusicDetail(generics.RetrieveAPIView): queryset = Music.objects.all() serializer_class = MusicSerializer
代碼詳解:
代碼比較簡單,主要就是繼承restframework框架的通用視圖函數generics,或者APIView。若是先省事,建議generics,由於提供的通用視圖能夠容許你快速構建與數據相關的API視圖,固然若是以爲通用視圖不適合本身的API需求,可使用APIView類。
(在這裏兩種方式都用到了,能夠對比他們的區別)
模擬請求API接口(GET、POST請求)
自帶的測試頁面:
剛開始接觸到RESTful方面的知識仍是很是懵的,對網上不少文章感受講的也不是很全面,因此索性總結一下,而後接觸到RESTFramework框架也發現到了不少在Django方面不熟悉的地方,如CBV模式,以及工做的原理,有些都牽扯到框架內的源碼,也是從網上一些優秀的文章一點點慢慢了解到,以後對Django RESTframework相關知識也會繼續總結學習,下面是我在網上參考的一些文章,有興趣的能夠了解一下。
參考連接:
http://www.javashuo.com/article/p-qqxnnbjs-ct.html
https://www.cnblogs.com/renpingsheng/p/9534984.html#FeedBack
https://www.jianshu.com/p/08a998f74ac7