Django-REST-framework 基本教學 - 從無到有 DRF-Beginners-Guide 📝
透過 Django REST framework ( DRF ) 建立 REST API 非常方便快速,
在這裡教大家建立自己的第一個 Django-REST-framework 😄
建議對 Django 還不熟的人,可以先閱讀我之前寫的 Django 基本教學 - 從無到有 Django-Beginners-Guide,
先建立一些基本觀念,再來看 DRF 會比較清楚。
請先確認電腦有安裝 Python
請在你的命令提示字元 (cmd ) 底下輸入
安裝 Django
pip install django
pip install djangorestframework
基本上安裝應該沒什麼問題。
請記得要將 Django-REST-framework 加入設定檔
請在 settings.py 裡面的 INSTALLED_APPS 加入下方程式碼 (下圖)
INSTALLED_APPS = (
...
'rest_framework',
...
)先建立一個觀念,在 Django 中,通常我們會依照 功能 去建議一個 App , 例如範例的 musics ,代表他是 管理音樂 的部份。
有了這個觀念之後,我們動手開始做吧~
請在你的命令提示字元 (cmd ) 底下輸入
python manage.py startapp musics
建立完請記得要將 App 加入設定檔
請在 settings.py 裡面的 INSTALLED_APPS 加入 musics (也就是你自己建立的 App 名稱)
定義出資料庫中的結構(schema),並且透過 Django 中的指令去建立資料庫。
Django 預設是使用 SQLite ,如果想要修改為其他的資料庫,可以在 settings.py 裡面進行修改。
首先,請先在 models.py 裡面增加下方程式碼 (下圖)
from django.db import models
# Create your models here.
class Music(models.Model):
song = models.TextField()
singer = models.TextField()
last_modify_date = models.DateTimeField(auto_now=True)
created = models.DateTimeField(auto_now_add=True)
class Meta:
db_table = "music"接著在命令提示字元 (cmd ) 底下輸入
python manage.py makemigrations
python manage.py migrate
makemigrations : 會幚你建立一個檔案,去記錄你更新了哪些東西。
migrate : 根據 makemigrations 建立的檔案,去更新你的 DATABASE 。
執行完上面的指令之後,
你可以使用SQLiteBrowser 或 PyCharm 觀看 DATABASE,
你會發現多出一個 music 的 table ( 如下圖 )
有沒有注意到我們明明在 models.py 裡面就沒有輸入 id ,可是 database 裡面卻有 id 欄位,
這是因為 Django 預設會幫你帶入,所以可以不用設定。
Serializers 序列化 是 DRF 很重要的一個地方 ⭐
主要功能是將 Python 結構序列化為其他格式,例如我們常用的 JSON。
在 musics 裡面新增 serializers.py,並輸入下方程式碼
from rest_framework import serializers
from musics.models import Music
class MusicSerializer(serializers.ModelSerializer):
class Meta:
model = Music
# fields = '__all__'
fields = ('id', 'song', 'singer', 'last_modify_date', 'created')如果你想要全部 fields ,可以使用第 8 行的寫法。
2017/9/8
增加 SerializerMethodField 使用方法 ,可參考 serializers.py, days_since_created 為例
class MusicSerializer(serializers.ModelSerializer):
days_since_created = serializers.SerializerMethodField()
class Meta:
model = Music
# fields = '__all__'
fields = ('id', 'song', 'singer', 'last_modify_date', 'created', 'days_since_created')
def get_days_since_created(self, obj):
return (now() - obj.created).days在 Django 基本教學 - 從無到有 Django-Beginners-Guide 中我們使用 views,
而在 DRF 中提供我們可以使用另一種稱為 viewsets 。
請在 views.py 裡輸入下方程式碼 (下圖)
# Create your views here.
from musics.models import Music
from musics.serializers import MusicSerializer
from rest_framework import viewsets
# Create your views here.
class MusicViewSet(viewsets.ModelViewSet):
queryset = Music.objects.all()
serializer_class = MusicSerializer只需要寫這樣,你就擁有 CRUD 的全部功能,是不是非常強大 😮
為什麼呢? 因為 DRF 的 viewsets.ModelViewSet 裡面幫你定義了這些功能,
當然,如果你需要,也可以覆寫他。
DRF 提供 DefaultRouter 讓我們快速建立 Routers 路由。
請先將 urls.py 裡面增加一些程式碼,如下圖
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.routers import DefaultRouter
from musics import views
router = DefaultRouter()
router.register(r'music', views.MusicViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include(router.urls))
]最後執行 Django , 然後瀏覽 http://127.0.0.1:8000/api/
你應該會看到如下圖
恭喜你,成功了 😄
接下來,讓我來測試 API 吧~
在測試 API 之前,大家必須先了解一下什麼是 REST API
REST API 全名為 RESTful API,它並不是一個新東西、新技術,它只是一個規範。
簡單說明 :
GET : 讀取資源
PUT : 替換資源
DELETE : 刪除資源
POST : 新增資源
PATCH : 更新資源部份內容
剩下更詳細的資料就麻煩大家 GOOGLE了,我在現在來 測試 API 😃
測試 API 的工具很多,在這裡我們使用 Postman ,大家可以用自己習慣的工具。
我們先來新增幾筆資料,如下圖
在 步驟1 的地方輸入你的 API 的網址,範例為 http://127.0.0.1:8000/api/music/
在 步驟2 body 的地方,填入 song 和 singer 的值,然後按下 Send,
接著看 response ( 步驟3 ),也就是你新增進去 dabase 的資料。
如果你想一次看裡面全部的資料,可以使用 http://127.0.0.1:8000/api/music/
當按下 send 之後,會看到 response ( 步驟3 )的地方回傳修改後的值。
執行後,你會發現 id=3 的資料被刪除了。
在 REST API 中,授權很重要,如果沒有授權,別人一直任意不受限制的操作你的 API ,很危險,
所以 DRF 有提供 Authentications,讓我們來試試看吧~
首先,請在 views.py 裡面新增 permission_classes
# Create your views here.
from musics.models import Music
from musics.serializers import MusicSerializer
from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticated
# Create your views here.
class MusicViewSet(viewsets.ModelViewSet):
queryset = Music.objects.all()
serializer_class = MusicSerializer
permission_classes = (IsAuthenticated,)接著在 urls.py 裡面增加 api-auth
from django.conf.urls import url, include
from django.contrib import admin
from rest_framework.routers import DefaultRouter
from musics import views
router = DefaultRouter()
router.register(r'music', views.MusicViewSet)
urlpatterns = [
url(r'^admin/', admin.site.urls),
url(r'^api/', include(router.urls)),
url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))
]最後執行 Django , 然後瀏覽 http://127.0.0.1:8000/api/ ,你會發現右上角多了 Log in 的按鈕
我們先使用我們在 Django 基本教學 - 從無到有 Django-Beginners-Guide 裡面學到的 建立超級使用者
python manage.py createsuperuser
讓我們再次使用 POSTMAN,我們用 GET 當作範例
有注意到嗎? response 說我沒有 授權,
所以這時候我們就必須再加上授權才能操作 API (如下圖),我們可以操作 API 了
我的 帳號/密碼 設定為 twtrubiks/password123
在 REST framework 中有一個 Parser classes ,這個 Parser classes 主要是能控制接收的 Content-Type ,
例如說我規定 Content-Type 只接受 application/json ,這樣你就不能傳其他的 Content-Type ( 舉例 : text/plain ) 。
通常如果沒有特別去設定 ,一般預設是使用 application / x-www-form-urlencode ,不過預設的可能不是你想要的或是
說你想要設計只允許規範一種 Content-Type 。
設定 Parsers 也很簡單,如果你希望全域的設定,可以加在 settings.py,
這樣就代表我只允許 Content-Type 是 application/json 。
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': (
'rest_framework.parsers.JSONParser',
)
}也可以針對特定 view 或 viewsets 加以設定 ,直接在 views.py 加上 parser_classes 即可
class MusicViewSet(viewsets.ModelViewSet):
queryset = Music.objects.all()
serializer_class = MusicSerializer
permission_classes = (IsAuthenticated,)
parser_classes = (JSONParser,)當然,parser_classes 不只有 JSONParser,還有 FormParser , MultiPartParser 等等
我們使用 REST framework 時,難免會有想要制定額外的 route ,這時候我們可以利用
@detail_route 或 @list_route。
範例程式碼可參考 views.py
detail_route
使用方法很簡單,直接加上裝飾器 @detail_route 即可
@detail_route(methods=['get'])
def detail(self, request, pk=None):
music = get_object_or_404(Music, pk=pk)
result = {
'singer': music.singer,
'song': music.song
}
return Response(result, status=status.HTTP_200_OK)以上面這個例子來說, URL pattern: /api/music/{pk}/detail/,
如果你沒有額外指定,通常你的 url_path 就是你 function 命名的名稱,
當然,我們也可以自己額外定義 url_path,只需要加上 url_path 參數,
範例如下
@detail_route(methods=['get'], url_path='detail_self')
def detail(self, request, pk=None):
music = get_object_or_404(Music, pk=pk)
result = {
'singer': music.singer,
'song': music.song
}
return Response(result, status=status.HTTP_200_OK)以上面這個例子來說, URL pattern: /api/music/{pk}/detail_self/,
這樣就不會使用你的 function 做為 url_path 了。
list_route
使用方法很簡單,直接加上裝飾器 @list_route 即可
@list_route(methods=['get'])
def all_singer(self, request):
music = Music.objects.values_list('singer', flat=True).distinct()
return Response(music, status=status.HTTP_200_OK)以上面這個例子來說,URL pattern: /api/music/all_singer/
他也有 url_path 的特性,如果要自定義,只需要加上 url_path 參數。
看完了以上的例子,相信大家可以分辨 @detail_route 以及 @list_route的不同。
先簡單介紹一下大家常聽到的 TDD 以及 BDD
TDD : Test-Driven Development。
BDD : Behavior-driven development 。
詳細地請大家再自行 GOOGLE,這邊要講 DRF 的 Testing,
或是你也可以參考我寫的範例 tests.py
- Create a music with API.
- Retrieve a music with API.
- Partial Update a music with API.
- Update a music with API.
- Delete a music with API.
- Retrieve a music detail with API.
- Get All singer with API.
Music
-
/api/music/ (Music create and list endpoint)
-
/api/music/{music-id}/ (Music retrieve, update and partial update and destroy endpoint)
-
/api/music/{music-id}/detail/ (Music retrieve detail endpoint)
-
/api/music/all_singer/ (Music list singer endpoint)
Usage
python manage.py test因為本範例剛好只有建立一個 APP ,如果你有很多個 APP ,你也可以指定
你要測試的 APP,範例如下
python manage.py test [app 名稱]python manage.py test musics恭喜你,基本上到這裡,已經是一個非常簡單的 Django-REST-framework ,趕快動手下去玩玩吧 😛
也可以觀看下一個範例
DataTables (server-side) 搭配 Django REST framework 簡單範例
DRF-dataTable-Example-server-side
- Python 3.4.3
MIT license























