基於Django RESTframework設計Restful API

導語

  關於RESTful的問題,在最近的面試中遇到不少,以前有過必定的瞭解,但沒有系統性的總結分析。因此如今結合Django RESTframework來加深對RESTful的理解,同時梳理這過程的一些知識點。html

什麼是RESTful?

 這個問題是最容易想到的,首先要分析這個問題,網上的其餘文章都會講到有關REST(Representational State Transfer),中文翻譯:」表述性狀態傳遞「,再白話一點就是對資源的表述性狀態傳遞。剛開始,看到這裏頭都大了,那咱們來看看其中比較關鍵須要瞭解到的知識點。前端

Resources(資源)

 這裏的資源指的是網絡上的每個實體,而每個實體都有着對應的URI(統一資源標識符),若是須要訪問這個資源,能夠經過訪問它的URI便可。python

Representation(表現層)

 簡單來講就是資源的表現形式,好比圖片、HTML、文本等等。面試

State Transfer(狀態轉化)

  客戶端能夠經過GET、POST、PUT、DELETE HTTP動詞來操做資源。數據庫

小結

  REST從資源的角度來審視整個網絡,將分佈再網絡中某個結點經過URI進行標識,而客戶端和服務端傳遞的是資源的某種表現層,而且客戶端經過HTTP動詞,對服務器資源操做,實現」表述性狀態轉化「。(表述性:客戶端請求一個資源,而且經過服務器拿到資源)
 知足以上這些約束條件和原則的應用程序或設計就是RESTful。換言之RESTful就是一種架構的規範和約束。django

RESTful API

對API的設計來說,RESTful是現在常見的的設計規範,一般用於Web數據接口的設計。這裏講講從網上大體總結的幾個RESTful API的設計細節。json

URI設計

一、動詞+賓語

 客戶端使用」動詞+賓語"的結構操做服務器資源,動詞指的是HTTP動詞,賓語指的是資源。HTTP動詞對應的服務器資源操做:後端

  • GET(SELECT):從服務器取出資源(一項或多項)。
  • POST(CREATE):在服務器新建一個資源。
  • PUT(UPDATE):在服務器更新資源(客戶端提供改變後的完整資源)。
  • PATCH(UPDATE):在服務器更新資源(客戶端提供改變的屬性)。
  • DELETE(DELETE):從服務器刪除資源。

二、賓語必須是名詞

 因爲賓語是API中的URI,是HTTP動詞做用的的對象,應該是名詞,而不是動詞。api

三、複數URI

 對於URI建議使用複數服務器

三、避免多級的URI

狀態碼

客戶端的每一次請求,服務器給出迴應,而回應包括HTTP狀態碼和數據兩部分。
HTTP狀態碼的含義:

  1. 1xx:相關信息
  2. 2xx:操做成功
  3. 3xx:重定向
  4. 4xx:客戶端錯誤
  5. 5xx:服務器錯誤

服務器迴應

一、不要返回純文本

 API返回的數據格式,不該該是一個純文本,應該是一個JSON對象,這樣才符合結構化流程。一樣服務器迴應的HTTP頭的Content-Type屬性一樣要設置爲application/json。

二、發生錯誤時,不要返回200狀態碼

 在發生錯誤的時候,不該該返回一個200狀態碼,而後把錯誤信息放在數據體裏,由於這樣會致使須要解析完數據體才能知道操做失敗。

Django RestFramework

Django RestFramework是一個基於Django上構建符合RESTful風格Web api,而且自身還帶有測試的頁面,方便測試本身的API,因此對於」先後端分離「的開發模式來說十分合適。

關於先後端分離

 先後端分離指的是後端來講只須要提供數據接口,再也不渲染模板,前端只須要獲取數據而且呈現。這樣的有許多優勢:

  • 先後端解耦,接口複用,減小開發量
  • 各司其職,先後端同步開發,提高工做效率,定好接口規範
  • 更利於調試、測試和運維

Django RestFramework簡介

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後,首先執行中間件的方法,而後在進行路由匹配。

基於Django RESTframework設計Restful API

 當路由匹配後,會執行自定義類中的as_view()方法,若是不存在則會調用父類的as_view()方法,最後再調用到dispatch()方法處理不一樣request請求,執行不一樣的方法。(這段過程當中設計到Django CBV模式的處理流程,以及一些源碼知識)

Django RESTframework使用

項目配置

安裝Django restframework:

pip install djangorestframework

基於Django RESTframework設計Restful API

新建項目,新建應用,修改settings.py

django-admin startproject Crawl
cd Crawl
python manage.py startapp music

settings.py(將rest_framework新增到INSTALLED_APPS)

基於Django RESTframework設計Restful API

(其他的修改數據庫配置、修改語言、時區就不一一列出來)
項目文件樹:

基於Django RESTframework設計Restful API

項目設計數據庫

設計一個有關於存儲歌曲的詳細信息表(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

Serializers

建立一個序列化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

Views.py和Urls.py

經過前面提到的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請求)
基於Django RESTframework設計Restful API

基於Django RESTframework設計Restful API
基於Django RESTframework設計Restful API

自帶的測試頁面:
基於Django RESTframework設計Restful API

總結

剛開始接觸到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

相關文章
相關標籤/搜索