React กับ Django สามารถทำงานร่วมกันได้ไม่ยากอย่างที่คิด
Django เป็น backend Framework ที่ใช้งานได้ง่ายหลาย ๆ คนอาจคิดว่ามันใช้งานได้แค่ none-framework จริง ๆ แล้วมันใช้งานคู่กับ framework อื่น ๆ ได้ด้วยเช่นกันโดยใช้ Django Rest Framework (DRF) ซึ่งเป็นตัวที่ทำให้เราสร้าง REST API ขึ้นมาเพื่อใช้ในการติดต่อกับ frontend ได้เพราะฉะนั้นวันนี้เราจะมาลองเขียน React + Django ดูกันว่าถ้าเกิด Django ทำงานร่วมกับ framework อื่นมันยากง่ายแค่ไหนโดยบทความนี้จะทดลองสร้างเว็บง่าย ๆ ก่อนคือการดึงข้อมูลจาก database มาแสดงบนหน้าเว็บเกริ่นมาได้พอสมควรแล้วมาเริ่มกันเลยดีกว่าครับ
เรามาเริ่มกันต้องแต่กันตั้งค่าที่อยู่ไฟล์กันเลยดีกว่าครับในที่นี้ผมจะวางไฟล์ไว้ที่ drive c โดยเปิด command line console ขึ้นมาแล้วก็สั่งสร้างไฟล์ตามนี้เลย
$ mkdir myhero && cd myhero
$ mkdir backend && cd backend
สร้างที่อยู่โฟเดอร์เสร็จแล้วต่อไปก็คือการ set up django project อย่างแรกต้องติดตั้งตัว virtual env เอาไว้เก็บ package ต่าง ๆ ที่เราใช้กับ project นี้โดยติดตั้งตามนี้ครับ
$ python -m pip install --user virtualenv $ python -m venv env
จากนั้นเราต้อง activate ตัว env ที่เราได้สร้างไว้ด้วยแล้วค่อยติดตั้ง package ที่เอาไว้ใช้ใน project ตามนี้ครับ สามารถอ่านเรื่อง virtualenv เพิ่มเติมได้ที่นี่
สำหรับ Linux and OS X
$ source env/bin/activate
สำหรับ Window
./> env\Scripts\activate
ติดตั้ง django
(env) pip install django
เมื่อเราได้ติดตั้ง django แล้วถัดมาสร้างโปรเจกต์ django กันดีกว่า
(env) django-admin startproject hero_api
(env) cd hero_api
(env) python manage.py startapp heros
จะเห็นว่าเราได้สร้างทั้ง project และ app เมื่อเราได้สร้าง app ใน django สิ่งที่เราควรทำอย่างแรกเลยคือไปที่ settings.py แล้วเพิ่ม app ลงใน INSTALLED_APPS
# hero_api/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'heros', # เพิ่ม app เข้ามาใหม่
]
มาถึงตรงนี้แล้วอยากให้ทุกคนทดลองรัน project ของเรากันสักหน่อยครับ
(env) python manage.py runserver
เราจะสร้าง Hero model เพื่อเอาไว้เก็บข้อมูล Hero ซึ่งจะมีอยู่สอง fields คือ name ,
description
# heros/models.py
from django.db import models
class Hero(models.Model):
name = models.CharField(max_lenght=100)
description = models.TextField()
def __str__(self):
return self.name
ทุกครั้งที่สร้าง model ขึ้นมาใหม่ต้องทำการ migrate มันก่อนเพื่อให้มันขึ้นไปอยู่ใน database ของเราซึ่งขั้นตอนก็ไม่ยากเราจะต้องสั่ง command line ตามนี้
(env) python manage.py makemigrations (env) python manage.py migrate
เพื่อให้เราสามารถดูข้อมูลและเพิ่มข้อมูลใน Hero model ได้ง่ายโดยสามารถไปใช้หน้า admin ที่ django ทำขึ้นมาให้อยู่แล้วได้แต่เราต้องเพิ่ม model เข้าไปในหน้า admin เองไปที่ admin.py แล้วเพิ่มโค้ดตามนี้ก่อนที่จะเข้าหน้า admin ได้เราต้องสร้าง superuser ขึ้นมาก่อน
(env) python manage.py createsuperuser
เมื่อสร้างเสร็จแล้วมาทดลองเข้าหน้า admin กันดีกว่าครับ
(env) python manage.py runserver
เมื่อรันเซิร์ฟเวอร์เสร็จแล้วไปที่ http://127.0.0.1:8000/admin แล้วก็ Login ตามรหัสที่เราได้สร้างเป็น superuser ไว้ได้เลย
ตอนนี้เรายังไม่มีข้อมูลใน database เราสามารถเพิ่มข้อมูลได้โดยกดไปที่ Add แล้วก็เพิ่มข้อมูล Hero สัก 3 คนตามนี้ครับ
Django
Rest Framework
เราจะใช้ Djago Rest Framework (DRF) เป็นตัวสร้าง REST APIs เพื่อเป็นตัวติดต่อกับ frontend framework โดยก่อนจะใช้ต้องติดตั้งกันก่อน
(env) pip install djangorestframework
ก่อนที่เราจะเอา Rest Framework ไปใช้ต้องไปเพิ่มเข้าใน INSTALLED_APPS
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', #เพิ่มมาใหม่ 'heros', ]
ในการใช้ Rest Framework เราต้องมีการตั้งค่าการเข้าถึงด้วยถ้าเราทำขึ้นโปรเจกต์แบบจริงจังเพื่อความปลอดภัยของข้อมูลเราต้องตั้งค่าเกี่ยวกับการเข้าถึงแต่ตอนนี้เราแค่ทดลองเฉยๆเพราะฉะนั้นใส่ตามนี้ได้เลย
REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.AllowAny', ] }
เราจะเริ่มสร้าง url กันก่อนแต่อาจจะเป็น url ที่ยังไม่สามารถเข้าได้นะเพราะยังไม่มี view เราค่อยสร้างทีหลังตอนนี้เริ่มออกแบบ url กันก่อนที่คิดไว้เราจะเป็นเว็บที่แสดงรายชื่อฮีโร่ก็คือเมื่อไป /hero จะแสดงรายชื่อ hero ทั้งหมดแต่ถ้า /hero/<id> /hero/<id> จะแสดงรายชื่อ hero แต่ละคนซึ่งเราสามารถเรียก hero แต่ละคนผ่านทาง id มันจะไปอิงตาม id ที่อยู่ใน database แล้วก็จะดึงข้อมูลตาม id ที่เราเรียกถึงเช่นถ้าเราต้องการเรียก hero คนแรกก็จะพิม /hero/1 ถ้าตัวที่สองก็ /hero/2 ตามลำดับ
ดังนั้นเรามาสร้างตามที่เราพูดกันเลยดีกว่าครับไปที่ urls.py แล้วเพิ่ม url ตามนี้ครับ
from django.contrib import admin from django.urls import include, path urlpatterns = [ path('admin/', admin.site.urls), path('api/', include('heros.urls')), ]สร้างไฟล์ urls.py ที่โฟลเดอร์ heros แล้วเพิ่มโค้ดตามนี้ได้เลย# heros/urls.py from django.urls import path from . import views urlpatterns = [ path('', views.ListHero.as_view()), path('<int:pk>/', views.DetailHero.as_view()), ]
Serializers
ในตอนนี้เรามี Models และได้สร้าง URL แล้วแต่ไม่ได้มีการ
return อะไรไปเลยดังนั้นเราต้องใช้ Serializers ในการ return ข้อมูลกลับไปเป็น JSON เพิ่อให้ง่ายต่อการเข้าถึงข้อมูล
หลายคนอาจจะสงสัยว่า เอ๊ะ
เรากำลังทำสิ่งนั้นอยู่หรือเปล่า ใช่เรากำลังสร้าง API
แล้วถามว่าทำไมถึงต้องใช้ Serializers เหตุผลมันง่ายมากๆ
คือมันจะแปลงข้อมูลของเราที่ส่งออกไปเป็นรูปแบบ JSON เพื่อให้ทุกคนเข้าใจข้อมูลที่เราส่งออกไปและสามารถเรียกใช้มันได้ง่ายอีกด้วย
เริ่มสร้างกันเลยดีกว่าอย่างแรกให้สร้าง serializers.py ขึ้นมาใหม่ในโฟลเดอร์ heros และเพิ่มโค้ดตามนี้เลย
# heros/serializers.py from rest_framework import serializers from .models import Hero class HeroSerializer(serializers.ModelSerializer): class Meta: fields = ( 'id', 'name', 'description', ) model = Hero
เราจะ import serializers จาก DRF และ Hero จากไฟล์ models.py เราได้สร้าง class HeroSerializers ซึ่งจะเห็นว่ามันมีรูปแบบคล้ายมาก ๆ กับการสร้าง model หลังจากกำหนด fields เรียบร้อยแล้วเราก็กำหนด model ที่เราอ้างถึงในที่นี้คือ Hero และอย่าลืมว่า id ตัวนี้ django ได้สร้างมาให้เราแบบ auto แล้วใน model เราเลยไม่ต้องกำหนดมันแต่เราต้องการเอา id มาใช้เพิ่ออ้างถึง Hero แต่ละคนเราจึงต้อง return มันออกมาด้วย
ใน regular Django นั้นเวลาเราสร้าง view นั้นเพื่อส่งข้อมูลหรือแสดงผลอะไรสักอย่างในหน้า templates ใน DRF view นั้นเราทำเหมือนกันแต่เพื่อแสดงข้อมูล serializers รูปแบบการเขียนของ DRF view นั้นคล้ายกับ Regular Django แล้วยังมี generic views ใช้สำหรับแสดงผล เรามาเริ่มเขียน Views กันดีกว่าครับเราจะสร้างสอง View ก็คือ ListHero , DetailHero โดยจะใช้ generics view ที่แตกต่างกันสามารถดูได้ตามโค้ดด้านล่างเลยครับ
# heros/views.py from rest_framewrk import generics from .models import Hero from .serializers import HeroSerializer class ListHero(generics.ListCreateAPIView): queryset = Hero.objects.all() serializer_class = HeroSerializer class DetailHero(generics.RetrieveUpdateDestroyAPIView): queryset = Hero.objects.all() serializer_class = HeroSerializer
Browsable API
เราสามารถเรียกดูหรือทดสอบ api ได้หลาย ๆ ทางอาจจะผ่านทาง Postman หรืออื่น ๆ แต่ DRF ยังสามารถทดสอบ api ผ่านทางเว็บบราวเซอร์
มาทดลองรันกันดีกว่าครับว่าตอนนี้มันแสดงผลอย่างไรบ้าง
(env) python manage.py runserver
และไปที่ลิ้งค์นี้ http://127.0.0.1:8000/api/ แสดงผลตามนี้
จะเห็นว่าเราสามารถดูได้ว่าข้อมูลที่อยู่ใน
api ของเรามีอะไรบ้างรูปแบบเป็นแบบไหนบ้างซึ่งออกมาในรูปแบบ
Json ซึ่งง่ายต่อการดูมาก ๆ
และยังสามารถเพิ่มข้อมูลใหม่ได้อีกด้วย
ในหน้าต่อไปเป็นการดู Hero แบบเจาะจงตัวโดยเราจะไปที่ลิ้ง http://127.0.0.1:8000/api/(เลข id ของข้อมูล) เช่นถ้าเรียก
http://127.0.0.1:8000/api/1
จะได้หน้านี้
"สำหรับบทความ Django Rest Framework with React.js ใน Ep.1 ก็จะขอจบลงเพียงเท่านี้ก่อนครับ มาถึงตรงนี้ผมก็หวังว่าเพื่อน ๆ คงจะเริ่มมองเห็นภาพรวมกันพอสมควรกันแล้วนะครับ แต่บทความในซีรีย์นี้ยังไม่จบนะครับ เดี๋ยวผมจะมาต่อใน Ep.2 ซึ่งเป็น Ep สุดท้ายกันครับ ถ้าเพื่อน ๆ มีความเห็นหรือคำแนะนำตรงไหน ก็คอมเมนต์ได้ที่ด้านล่างเลยนะครับ ไม่ว่าจะเป็นคำแนะนำ หรือคำติชม ผมก็ยินดีมาก ๆ ครับ" พบกันต่อใน Ep.2 ครับ
ติดตามต่อได้ใน Django with React.js
ฝาก YouTube Channel ของ STACKPYTHON กันด้วยนะครับ
หรือเข้าดูคอร์สไพธอนของเราได้ที่
กิจกรรมที่กำลังจะมาถึง
ไม่พลาดกิจกรรมเด็ด ๆ ที่น่าสนใจ
Event นี้จะเริ่มขึ้นใน April 25, 2023
รายละเอียดเพิ่มเติม/สมัครเข้าร่วมคอร์สเรียนไพธอนออนไลน์ที่เราได้รวบรวมและได้ย่อยจากประสบการณ์จริงและเพื่อย่นระยะเวลาในการเรียนรู้ ลองผิด ลองถูกด้วยตัวเองมาให้แล้ว เพราะเวลามีค่าเป็นอย่างยิ่ง พร้อมด้วยการซัพพอร์ตอย่างดี