Django REST Framework - สร้าง API ด้วย Python ฉบับเต็ม

สร้าง REST APIs ด้วย Django REST Framework ฉบับเต็ม

Django REST Framework - สร้าง API ด้วย Python ฉบับเต็ม

Django REST Framework คือ toolkit หรือไลบรารีของ Python ในการสร้าง RESTful APIs ได้อย่างรวดเร็วและสมบูรณ์แบบ ในบทความนี้จะมาอธิบายการสร้าง RESTful APIs และพื้นฐานต่าง ๆ ที่จำเป็นต้องรู้ พร้อมทั้งได้ Web Service/API เป็นของตัวเองด้วยการ deploy ไปที่ PaaS (Platform as a Service) อย่าง Heroku และใน Ep ถัดไปซึ่งเป็นบทความที่ 2 เป็น (Final EP) จะเป็นการใช้งาน Vue.js ร่วมกับ Django REST Framework

Prerequisite

ปล.ถ้ายังไม่มีพื้นฐาน Django แนะนำบทความ - พัฒนาเว็บไซต์ด้วย Django เฟรมเวิร์คฉบับสมบูรณ์ ปี 2023

Table of Contents

  1. REST คืออะไร
  2. Django vs Django REST Framework
  3. ทำไมต้อง Django REST Framework
  4. HTTP Method & Status Code
  5. Virtual Environment
  6. ติดตั้ง Django & Django REST Framework
  7. Django project & app
  8. Database Model (SQLite)
  9. Serializers
  10. Views
  11. URLs
  12. Permission & Authentication (pending)
  13. CORS (Cross Origin Resource Sharing) (pending)
  14. Deploying to Heroku (pending)

REST คืออะไร ?

REST : REpresentational State Transfer คือสถาปัตยกรรมอย่างหนึ่งของซอฟต์แวร์ที่อยู่บนพื้นฐานของ HTTP Protocol ถึงแม้เราจะมองไม่เห็นแต่ว่ามันมีอยู่จริง (แน่นอนละ เพราะมันเกี่ยวข้องกับซอฟต์แวร์ จะมองเห็นได้ไงเนอะ) โดยจะมี 2 ตัวละครหลักคือ Client และ Server

6 คุณลักษณะที่บ่งบอกตัวตนของ RESTful

ตรงส่วนนี้ขอไม่อธิบายรายละเอียดมาก อาจจะต้องไปหาข้อมูลเพิ่มเติมครับ ถือว่าให้เป็นคีย์เวิร์ดไปสืบค้นต่อไป

บทความแนะนำ/อ่านเพิ่มเติม What is a REST API

Django vs Django REST Framework

เชื่อว่าหลายคนอาจจะยังมีข้อสงสัยที่ว่า Django กับ Django REST Framework นั้นแตกต่างกันอย่างไร ซึ่งขอยกเอา discussion ที่น่าสนใจในเว็บ stackoverflow มาเป็น reference ในครั้งนี้ครับ ดังนั้นจึงขอสรุปให้แบบเนื้อ ๆ

เลือก

Note: จริง ๆ แล้วเราสามารถที่จะเขียนและสร้าง API ด้วย Django แบบปกติคือเรียกว่า build from scratch ได้เลย แต่เมื่อมี tool อย่าง REST Framework แล้ว ก็ไม่มีเหตุผลที่จะไป re-invent the wheels หรือสร้างอะไรสักอย่างที่มันดีและมีอยู่แล้วขึ้นมาใหม่นั่นเอง

ทำไมต้อง Django REST Framework

นี่คือเหตุผลบางส่วนว่าทำไมต้องใช้ Django REST Framework

HTTP Method & Status Code

ทั้งสองส่วนนี้เรียกได้ว่ามีบทบาทสำคัญสำหรับการสร้าง RESTful APIs ไปทำความเข้าใจทั้งสองส่วนนี้กันได้เลย

HTTP Methods (GET, POST, PUT, DELETE)

HTTP methods นั้นก็แทบจะเรียกไว้ว่าสื่อความหมายและอธิบายได้ในตัวมันเอง (Self-explanatory) และตรงไปตรงมา ซึ่งทั้ง 4 เมธอดดังต่อไปนี้มีความนิยมและพบเจอได้บ่อยที่สุด

ซึ่งจริง ๆ แล้ว HTTP Methods ไม่ได้มีเพียงแค่ 4 ตัวนี้ ยังมีตัวอื่น ๆ เช่น HEAD, PATCH, CONNECT, TRACE, OPTIONS ดังนั้นมีลิ้งค์อ้างอิงในท้ายบทความ สามารถไปศึกษาเพิ่มเติมได้เลยครับ

Note: Safe method: GET เพราะว่าไม่ได้ทำให้ข้อมูล (data/resource) ใน server มีการเปลี่ยนแปลง ส่วน POST , PUT , DELETE เป็น unsafe methods เพราะว่าทำให้ข้อมูลใน server เกิดการเปสี่ยนแปลง ถ้าเคยเขียน Django มาก่อน เช่นในหน้า HTML form นั้นถ้ามีการใช้งานเมธอด POST จะต้องใส่แท็กของ CSRF token เข้าไปช่วยป้องกันทุกครั้ง

Status Codes

ซึ่งโดยปกติแล้ว status codes ที่เรามักจะพบเจอบ่อย ๆ มีดังนี้

Virtual Environment

ทำการสร้างโฟลเดอร์เพื่อเก็บโปรเจคท์พร้อมทั้งสร้าง virtual environment ให้กับโปรเจคท์ (quick start)

# Create a folder to store our project
mkdir restframework

# ชี้ไปที่โฟลเดอร์ที่สร้างขึ้นมา
cd restframework

# สร้าง virtual environment ชื่อว่า env
python -m venv env

# Activate (เรียกใช้งาน) virtual environment (Windows)
env/Scripts/activate

# Virtual env ถูก activate และพร้อมใช้งาน
(env)

คลิปวิดีโอแนะนำ (Youtube) - Virtual Environment คืออะไร

ติดตั้ง Django & Django REST Framework

ทำการติดตั้ง Django และ Django REST Framework ผ่าน pip

(env) pip install django
(env) pip install djangorestframework

Django project & app

เมื่อทำการติดตั้ง Django และ Django REST Framework เสร็จแล้ว ก็จะเป็นการเริ่มต้นสร้างโปรเจคท์และแอพ

(env) django-admin startproject mysite .
(env) cd mysite
(env) python manage.py startapp api

requirements.txt

(env) pip freeze > requirements.txt

จะมีแพ็คเกจและไลบรารีที่ติดตั้งดังนี้

asgiref==3.3.4
Django==3.2.2
djangorestframework==3.12.4
pytz==2021.1
sqlparse==0.4.1
typing-extensions==3.10.0.0

Project Structure

├── .gitignore
└── restframework
    ├── db.sqlite3
    ├── mysite
   ├── __init__.py
   ├── asgi.py
   ├── settings.py
   ├── urls.py
   └── wsgi.py
    ├── manage.py
    ├── api
   ├── __init__.py
   ├── admin.py
   ├── apps.py
   ├── migrations
   ├── 0001_initial.py
   └── __init__.py
   ├── models.py
   ├── tests.py
   └── views.py
    └── requirements.txt

ทำการรีจิสเตอร์แอพใน settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api',  # Oup app
    'rest_framework'  # DRF
]

Database Model - SQLite

เมื่อสร้างโปรเจคท์และแอพเสร็จเรียบร้อย ถัดมาก็จะเป็นการสร้าง model ซึ่งในที่นี้จะหมายถึงการสร้าง class/object เพื่อติดต่อกับกับฐานข้อมูล เป็นอันว่ามักจะเข้าใจกันดีถ้าพูดถึง model นั้น แน่นอนว่าจะมีความเกี่ยวข้องกับ database นั่นเอง โดย database ที่ใช้ในโปรเจคท์นี้ก็จะใช้ SQLite ซึ่งเก็บข้อมูลในรูปแบบของไฟล์ ไม่ต้องทำการคอนฟิกเซิร์ฟเวอร์หรือพอร์ตอะไรต่าง ๆ ให้ยุ่งยาก เรียกได้ว่ามีมาให้กับ Django และพร้อมใช้กันได้เลย

Note: SQLite จะนิยมใช้กับโปรเจคท์เล็ก ๆ หรือไม่ว่าจะเป็นในช่วงของการ development ใน localhost เท่านั้น แต่ถ้าโปรเจคท์ใหญ่ ๆ มีผู้ใชเ้ยอะ ๆ มี concurrency สูง ๆ จะไม่เหมาะ แต่สำหรับคำแนะนำของผู้เขียน ถ้าจะ build โปรเจคท์จริง ๆ ควรใช้ PostgreSQL ทั้งในส่วนของ development และ production นั่นก็คือ keep the same environment as possible

**

ทำการออกแบบและสร้างตารางใน models.py

from django.db import models


class Task(models.Model):
    title = models.CharField(max_length=80)
    description = models.TextField()
    date_created = models.DateTimeField(auto_now_add=True)
    complete = models.BooleanField()

    class Meta:
        ordering = ['-date_created']
        db_table = 'task'
    
    def __str__(self):
        return self.title

จากนั้นทำการรันคำสั่งเพื่อ migrate database โดยต้อง makemigrations ก่อน

(env) python manage.py makemigrations

จะได้

Migrations for 'task':
  api\migrations\0001_initial.py
    - Create model Task

จากนั้นทำการ migrate

(env) python manage.py migrate

ตารางทุกตารางจะถูก migrate ไปที่ฐานข้อมูล SQLite เป็นอันเสร็จสิ้นขั้นตอน migrat่ion

Operations to perform:
  Apply all migrations: admin, api, auth, contenttypes, sessions
Running migrations:
  Applying contenttypes.0001_initial... OK
  Applying auth.0001_initial... OK
  Applying admin.0001_initial... OK
  Applying admin.0002_logentry_remove_auto_add... OK
  Applying admin.0003_logentry_add_action_flag_choices... OK
  Applying api.0001_initial... OK
  Applying contenttypes.0002_remove_content_type_name... OK
  Applying auth.0002_alter_permission_name_max_length... OK
  Applying auth.0003_alter_user_email_max_length... OK
  Applying auth.0004_alter_user_username_opts... OK
  Applying auth.0005_alter_user_last_login_null... OK
  Applying auth.0006_require_contenttypes_0002... OK
  Applying auth.0007_alter_validators_add_error_messages... OK
  Applying auth.0008_alter_user_username_max_length... OK
  Applying auth.0009_alter_user_last_name_max_length... OK
  Applying auth.0010_alter_group_name_max_length... OK
  Applying auth.0011_update_proxy_permissions... OK
  Applying auth.0012_alter_user_first_name_max_length... OK
  Applying sessions.0001_initial... OK

Serializers

serializer คือกระบวนการแปลง model object ไปเป็น JSON ฟอร์แมตเพื่อส่งไปที่ client หรือจะมีส่วนกลับอีกตัวที่มีชื่อว่า deserializer ที่ทำหน้าที่ตรงกันข้ามคือแปลง JSON ไปเป็น Django object เพื่อให้ Django สามารถอ่านเข้าใจได้

ทำการสร้างไฟล์ใหม่ขึ้นมาชื่อ serializers.py และทำการอิมพอร์ตโมดูล serializers เข้ามาเพื่อเรียกใช้งานคลาส ModelSerializer ซึ่งจะเป็นพระเอกในการ serialize ออปเจคท์นั่นเอง

serializers.py

from rest_framework import serializers
from .models import Task


class TaskSerializer(serializers.ModelSerializer):

    class Meta:
        model = Task
        fields = ('id', 'title', 'description', 'date_created', 'complete')

Views

Views คือส่วนของการเขึยน business logic ของ Django เช่นการจัดการกับ request/response ต่าง ๆ ซึ่งปกติแล้วจะมีรูปแบบการเขียนได้ 2 แบบ คือ Function Based (FBV) View และ Class Based View (CBV) ซึ่งในโปรเจคท์นี้จะเขียนแบบที่สอง เพราะว่าจะสามารถเรียกใช้ฟีเจอร์ต่าง ๆ ของ REST Framework ได้เต็มประสิทธิภาพ ซึ่งพระเอกของเราต่อไปนี้ก็คือโมดูล generics ที่ประกอบไปด้วย APIView ต่าง ๆ ให้เราสามารถเลือกใช้งานได้อย่างสะดวกและรวดเร็วมาก ๆ

ไปที่ไฟล์ views.py

from django.shortcuts import render
from .serializers import TaskSerializer
from .models import Task
from rest_framework import generics


class TaskList(generics.ListAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    
    # return Response(queryset.data)

**

Note: การเขียนแบบ Class Based View จะขึ้นต้นด้วยคีย์เวิร์ด class และตัวที่เป็น Function Based View จะขึ้นต้นด้วย def

บทความแนะนำ/อ่านเพิ่มเติม CBV vs FBV

URLs / Route / End-points

ต่อมาจะเป็นการกำหนด URLs ให้กับโปรเจคท์ โดยทำอิมพอร์ตโมดูล views จากแอพ api เข้ามาเพื่อเรียกใช้งานคลาสและออปเจคท์ต่าง ๆ ในโมดูล

ไปที่ไฟล์ mysite/urls.py

from django.contrib import admin
from django.urls import path, include
from api import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/tasks/', views.TaskList.as_view()),
]

RESTful Structure & URL endpoints

Endpoint –> Method –> Action

Browsable API

อีกหนึ่งจุดเด่นของ Django REST Framework คือมีหน้า Interface ที่ใช้สำหรับเรียกดู ทดสอบ API ได้ ซึ่งทำให้สะดวกมาก ๆ ในการพัฒนา ซึ่งเราจะเรียกหน้านี้ว่า Browsable API แปลเป็นไทยก็คือหน้า API ที่สามารถเรียกดูได้นั่นเอง

http://127.0.0.1:8080/api/tasks/

สังเกตเห็นว่าตอนนี้ยังไม่มีข้อมูลหรือ record ใด ๆ ใน URI นี้ ก็เพราะว่ายังไม่ได้มีการเพิ่มหรือบันทึกข้อมูล ๆ เข้ามานั่นเองครับ เลยยังแสดงเป็นลิสต์เปล่า ๆ []

สร้าง Superuser

ทำการสร้าง superuser เพื่อเข้าใช้งานหน้าแอดมินด้วยคำสั่ง createsuperuser

(env) python manage.py createsuperuser

จะขึ้น console ตามนี้ และจัดการกำหนด username และ password ให้เรียบร้อย

Username (leave blank to use 'user'): sonny
Email address: sonny_stackpython@gmail.com
Password:
Password (again):
The password is too similar to the username.
Bypass password validation and create user anyway? [y/N]: y
Superuser created successfully.

Note: password เป็น hidden field จะไม่แสดงให้เห็นในหน้าคอนโซล และ Email เป็น blank field สามารถปล่อยว่างได้

**

เข้าถึงหน้า admin site

ทำการสร้าง superuser เสร็จแล้วก็ทำการรีจิสเตอร์โมเดลใน admin โดยไปที่ไฟล์ admin.py จากนั้นทำการรีจิสเตอร์ตามปกติ

from django.contrib import admin
from .models import Task


# Register our model
admin.site.register(Task)

จากนั้นเข้าหน้าแอดมินและทำการเพิ่มข้อมูลเข้าไปสัก 1 record ดังภาพด้านล่าง

HTTP 200 OK
Allow: GET, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 1,
        "title": "Copy code from Stackoverflow",
        "description": "I have no idea, so I decided to copy code from Stackoverflow for my new project",
        "date_created": "2021-05-10T10:46:37.932394Z",
        "complete": false
    }
]

Response Header

อ่านเพิ่มเติม Content Type (mozilla.org)

http://127.0.0.1:8080/api/tasks/

http://127.0.0.1:8080/api/tasks/

ซึ่งถ้าสังเกตในคอนโซลจะพบว่ามีการรีเทิร์น status code เป็น 201 ซึ่งหมายถึงมีการสร้าง task ขึ้นมาใหม่สำเร็จ ซึ่งจะอธิบายในส่วนของ HTTP Methods และ Status Code

[10/May/2021 18:01:00] "POST /api/tasks/ HTTP/1.1" 201 9379

**

HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 2,
        "title": "Read articles on FreeCodeCamp",
        "description": "I must read articles on FreeCodeCamp everyday to boost my programming knowledge",
        "date_created": "2021-05-10T11:01:00.844176Z",
        "complete": true
    },
    {
        "id": 1,
        "title": "Copy code from Stackoverflow",
        "description": "I have no idea, so I decided to copy code from Stackoverflow for my new project",
        "date_created": "2021-05-10T10:46:37.932394Z",
        "complete": false
    }
]

**

Task Detail / Update / Delete

ต่อมาจะเป็นในส่วนของการเข้าดูรายละเอียดของแต่ละ task ซึ่งนั่นก็คือ Task Detail นั่นเอง ปกติแล้วเราต้องทำการเขียนฟังก์ชันเพื่อกำหนดแอคชั่นของแต่ละเมธอด ว่าจะให้เรียกดู อัปเดต เพิ่มหรือลบ แต่ด้วยความพิเศษของ genericsView ช่วยให้เราสามารถเขียนอยู่บนคลาสเดียวและจัดการให้เสร็จสรรพ

สร้างคลาสใหม่ที่มีชื่อว่า TaskDetail ใน views.py

...
class TaskList(generics.ListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer


# New
class TaskDetail(generics.RetrieveUpdateDestroyAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer

ทำการกำหนด end-point ใหม่ซึ่งจะอ้างอิงด้วย URL พารามิเตอร์ในรูปแบบของ pk คือ /int:pk ต่อท้าย tasks

อัปเดตโค้ดต่อไปนี้ใน mysite/urls.py

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/tasks/', views.TaskList.as_view()),
    path('api/tasks/<int:pk>', views.TaskDetail.as_view())  # New
]

```python

HTTP 200 OK Allow: GET, HEAD, OPTIONS Content-Type: application/json Vary: Accept

{ “id”: 1, “title”: “Copy code from Stackoverflow”, “description”: “I have no idea, so I decided to copy code from Stackoverflow for my new project”, “date_created”: “2021-05-10T10:46:37.932394Z”, “complete”: false }


##

###

## Permissions & Authentication

ตอนนี้สามารถสร้าง CRUD แอพได้เรียบร้อยแล้ว แต่ว่ายังเหลือระบบ permissions และ authentication เหตุผลก็เพราะว่า

- user ที่ได้ทำการยืนยันตัวตน (authenticated user) เท่านั้นถึงจะสามารถสร้าง task ได้
- user เจ้าของ task นั้น ๆ เพียงเท่านั้นที่สามารถ update หรือ delete ของตัวเองได้
- user ที่ไม่ได้ยืนยันตัวตนสามารถเข้าดู task ได้ แต่จะดูหรืออ่าน (read) ได้เท่านั้น จะไม่สามารถ create, update, delete ได้

### Permissions

เรียกใช้งาน  permissions  จาก

rest_framework  เพื่อทำการกำหนด permission ให้กับ user

จากนั้นทำการกำหนดตัวแปร  permisssion_classes  โดยกำหนดเป็น  permisssions.IsAuthenticated

คือต้องมีการ login เข้ามาเท่านั้นถึงจะสามารถเข้าถึงหน้านี้ได้

```python
from rest_framework import generics, permissions  # New
...
class TaskList(generics.ListCreateAPIView):
    queryset = Task.objects.all()
    serializer_class = TaskSerializer
    
    # Only an authenticated user can access this API endpoint
    permission_classes = [permissions.IsAuthenticated]
...

user ที่ไม่ได้ทำการล็อกอิน หรือไม่มี permission จะไม่สามารถเข้าถึงหน้านี้ได้

http://127.0.0.1:8080/api/tasks/

HTTP 403 Forbidden
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "detail": "Authentication credentials were not provided."
}

ล็อกอินผ่าน Browsable API

นอกจากนี้การล็อกอินผ่าน Browsable API นอกจากสะดวกแล้ว ยังทำให้รู้ได้ว่า user คนไหนที่กำลังใช้งานอยู่ โดยการตั้งค่า login/logout ผ่าน Browsable API ก็ทำได้ง่าย ๆ โดยทำการกำหนดเพิ่มใน URL ของโปรเจคท์

mysite/urls.py

urlpatterns = [
    ...
    path('api-auth/', include('rest_framework.urls'))  # New
]

Note: ชื่อ URL end-point จะต้ั้งเป็นชื่อไหนก็ได้ตามต้องการไม่จำเป็นต้องเป็น แต่ใน URL ใน Docs ที่กำหนดมาก็ถือว่า make sense ไม่มีเหตุผลต้องเปลี่ยน

ทำการรีเฟรช จะพบว่ามีข้อความแสดงสถานะการ login หรือไม่ ผ่าน Browsable API

Log in ผ่าน Browsable API

ซึ่งแน่นอนว่าตอนนี้มี user เพียงแค่ 1 นั่นก็คือ sonny และ user คนนี้มี task อยู่ทั้งสิ้น 2 tasks

Tasks ทั้งหมดของ sonny

สร้าง user ขึ้นมาอีก 1 user โดยสามารถสร้างผ่านด้วยวิธีการที่ง่ายที่สุดคือสร้างผ่านหน้าแอดมินได้เลย

เสร็จแล้ว SAVE

****

เพิ่ม user เข้ามาอีก 1 รวมเป็น 2 เพื่อทดสอบ

ตอนนี้มี 2 users คือ sonny และ Sam เรียบร้อยพร้อมทดสอบ จากนั้นให้ทำการล็อกอินผ่าน user ชื่อ Sam และสร้าง task ขึ้นมา 1 task

HTTP 201 Created
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 3,
    "title": "This is a task from Sam",
    "description": "A new task created by Sam",
    "date_created": "2021-05-12T05:32:56.891877Z",
    "complete": false
}
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

[
    {
        "id": 3,
        "title": "This is a task from Sam",
        "description": "A new task created by Sam",
        "date_created": "2021-05-12T05:32:56.891877Z",
        "complete": false
    },
    {
        "id": 2,
        "title": "Read articles on FreeCodeCamp",
        "description": "I must read articles on FreeCodeCamp everyday to boost my programming knowledge",
        "date_created": "2021-05-10T11:01:00.844176Z",
        "complete": true
    },
    {
        "id": 1,
        "title": "Copy code from Stackoverflow",
        "description": "I have no idea, so I decided to copy code from Stackoverflow for my new project",
        "date_created": "2021-05-10T10:46:37.932394Z",
        "complete": false
    }
]

ทดสอบเข้าดูที่ URL จะสังเกตว่าพอเข้ามาที่ URL end-point นี้แล้วมีสามารถทำได้ทุกอย่างไม่ว่าจะเป็นดึงข้อมูล (GET), เพิ่มข้อมูล (POST), อัปเดตข้อมูล (PUT), ลบข้อมูล (DELETE), etc

http://127.0.0.1:8080/api/tasks/1

Sam สามารถแก้ไข task ของ sonny ได้ ?

จะเห็นว่า Sam สามารถเข้าดูข้อมูลของ sonny และสามารถอัปเดตหรือลบข้อมูลในนี้ได้ ซึ่ง use case จริง ๆ ไม่ควรเป็นแบบนี้ ควรจะเป็น owner ของ task นั้น ๆ ที่มี permission ในการทำแบบนั้นได้เท่านั้น

ถือว่าจบไปแล้วเซสชั่นแรกกับ Django REST Framework - Tutorial ฉบับเต็ม ซึ่งในบทความนี้จริง ๆ แล้วยังไม่จบเพียงเท่านี้ครับ ยังมีอีก 2 - 3 หัวข้อที่จะมาทำการอัปเดตให้เพิ่มเติมคือ Authentication, Deployment (Heroku), etc ติดตามการอัปเดตในครั้งถัดไปได้เลยครับ และจะมีการเพิ่ม Vue.js สำหรับ Front-end ในการเรียกใช้งาน API ที่ได้สร้างไว้ผ่านไลบรารีที่มีชื่อว่า axios

สำหรับเพื่อน ๆ ที่อ่านจบแล้ว ถ้ารู้สึกชอบหรืออยากให้เขียนต่อให้จบไว ๆ หรือมีคำแนะนำตรงส่วนไหน ก็สามารถคอมเมนต์ไปที่โพสต์นี้ เพื่อส่งสารโดยตรงให้ผม ได้ปลุกไฟในตัว แล้วลุยเขียนให้จบสิ้นสนองความต้องการของผู้อ่านกันครับ ไปที่โพสต์บน Facebook

บทความแนะนำ/อ่านเพิ่มเติม Django REST Framework by Wasin

ปล.บทความด้านบนเป็นอีกบทความ Django REST Framework ฉบับภาษาไทยที่เขียนได้ค่อนข้างละเอียดมาก ๆ โดยพี่ Toey Wasin ที่จะสอนในคลาส Live ผ่าน Google Meet ในวันที่ 29 พฤษภาคมนี้ กับคอร์สสร้าง RESTful APIs ด้วย Django REST Framework with React.js สำหรับใครที่สนใจหรือยังไม่ได้ลงทะเบียนรีบด่วนครับ มีโปรโมชั่นอยู่

References

[ redhat.com ] - What is a REST API

[ djangostars.com ] - Why Use the Django REST Framework

[ developer.mozilla.org ] - HTTP Request Methods

[ developer.mozilla.org ] - HTTP Response Status Codes

[ stackoverflow.com ] - Django or Django REST Framework

[ django-rest-framework.org ] - Authentication & Permissions

[ django-rest-framework.org ] - Class-Based Views

📒Introduction to Django REST Framework (Course)