Contents

ใช้ Django APIs ด้วยวิธีง่ายๆ ด้วยเทมเพลต Django

เมื่อใช้เทคโนโลยีแบ็กเอนด์หรือเฟรมเวิร์ก เช่น Django, Laravel หรือ Node.js เพื่อเขียน REST API คุณต้องมีทักษะส่วนหน้าเพิ่มเติมโดยใช้เฟรมเวิร์ก เช่น React, Angular และ Vue เพื่อใช้ตำแหน่งข้อมูล API แต่นั่นไม่ได้เป็นเช่นนั้นเสมอไป คุณสามารถใช้ API ใน Django ได้โดยใช้เทมเพลต Django

การตั้งค่าโครงการ Django และจุดสิ้นสุด API

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

 mkdir payment_wallet_project
cd payment_wallet_project 

เพื่อปฏิบัติตามคำแนะนำนี้ คุณจะต้องสร้าง Application Programming Interfaces (API) ที่มีไว้สำหรับใช้ร่วมกับกระเป๋าเงินดิจิทัลที่ใช้ในธุรกรรมทางการเงิน

สามารถเข้าถึงซอร์สโค้ดที่สมบูรณ์ได้ผ่านพื้นที่เก็บข้อมูล GitHub ซึ่งพร้อมสำหรับการอ้างอิงและการสำรวจเพิ่มเติม

ในการเริ่มต้น ให้สร้างสภาพแวดล้อมเสมือนจริงโดยใช้ไลบรารี Pipenv เป็นรากฐานสำหรับบริบทการพัฒนาของโครงการของเรา

 pipenv install django djangorestframework 

การดำเนินการตามคำสั่งนี้จะส่งผลให้มีการติดตั้งไลบรารีที่จำเป็นและการสร้างสภาพแวดล้อมเสมือน

หากต้องการเปิดใช้งานสภาพแวดล้อมเสมือน โปรดดำเนินการคำสั่งต่อไปนี้ในเทอร์มินัลหรือพร้อมท์คำสั่งของคุณ:bashsource/venv/bin/activateกรุณาแทนที่ ด้วยเส้นทางจริงไปยังไดเรกทอรีโครงการของคุณบนคอมพิวเตอร์ของคุณ สิ่งนี้จะเปิดใช้งานสภาพแวดล้อมเสมือนและอนุญาตให้คุณใช้แพ็คเกจใด ๆ ที่ติดตั้งภายในนั้นสำหรับสคริปต์ Python ของคุณ

 pipenv shell

หากต้องการสร้างโปรเจ็กต์ Django ใหม่ ให้นำทางไปยังไดเร็กทอรีที่คุณต้องการและดำเนินการคำสั่ง “django-admin startproject PayApp” สิ่งนี้จะเริ่มต้นการสร้างโครงการใหม่ที่เรียกว่า"PayApp"ในตำแหน่งที่ระบุ

 django-admin startproject PayApp . 

การใช้เครื่องหมายวรรคตอนสรุป (. https://en.wikipedia.org/wiki/. ) ตามคำสั่ง “django-admin” จะช่วยลดโอกาสที่ การจำลองแบบซ้ำของโครงสร้างโฟลเดอร์หลักของโครงการภายในแอปพลิเคชัน Django ที่สร้างขึ้นใหม่

หากต้องการสร้างแอปพลิเคชัน Django ใหม่ภายในไดเรกทอรีโครงการที่มีอยู่ ให้ทำตามขั้นตอนเหล่านี้:1. เปิดเทอร์มินัลแล้วไปที่โฟลเดอร์รูทของโปรเจ็กต์ Django ของคุณโดยใช้คำสั่ง cd2. เมื่อคุณอยู่ในไดเร็กทอรีที่ถูกต้องแล้ว ให้รันคำสั่งต่อไปนี้เพื่อสร้างแอป Django ใหม่ชื่อ “myapp”:bashpython Manage.py startapp myapp3 สิ่งนี้จะสร้างไดเร็กทอรีใหม่ชื่อ"myapp"ภายในไดเร็กทอรี"apps"ภายในโปรเจ็กต์ Django ของคุณ ภายในไดเร็กทอรีนี้ คุณจะพบไฟล์หลายไฟล์ที่ประกอบเป็นโครงสร้างพื้นฐานของแอปใหม่ของคุณ

 python manage.py startapp wallet 

หากต้องการเริ่มสร้างแอปพลิเคชัน API โปรดปฏิบัติตามหลักเกณฑ์ที่ระบุไว้

การสร้าง Wallet REST API สำหรับการชำระเงิน

เพื่อที่จะใช้งานแบ็กเอนด์ที่ครอบคลุมสำหรับแอปพลิเคชันสกุลเงินดิจิทัลของคุณ จำเป็นต้องเปิดไฟล์ wallet/models.py ในโปรเจ็กต์ Django ของคุณ และสร้างแบบจำลองสองแบบแยกกันสำหรับกระเป๋าสตางค์และธุรกรรม โมเดลเหล่านี้จะทำหน้าที่เป็นรากฐานของสคีมาฐานข้อมูลของคุณและจัดเตรียมโครงสร้างที่จำเป็นสำหรับการจัดเก็บและเรียกข้อมูลที่เกี่ยวข้องกับบัญชีผู้ใช้และธุรกรรมภายในระบบ

 from django.db import models

class Wallet(models.Model):
   user = models.CharField(max_length=100)
   balance = models.DecimalField(max_digits=10, decimal_places=2)
   date_created = models.DateTimeField(auto_now_add=True)
   date_modified = models.DateTimeField(auto_now=True)

   def __str__(self):
       return self.user

class Transaction(models.Model):
   wallet = models.ForeignKey(Wallet, on_delete=models.CASCADE)
   amount = models.DecimalField(max_digits=10, decimal_places=2)
   timestamp = models.DateTimeField(auto_now_add=True) 

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

 from rest_framework import serializers
from .models import Wallet, Transaction

class WalletSerializer(serializers.ModelSerializer):
   class Meta:
       model = Wallet
       fields = '__all__'
class TransactionSerializer(serializers.ModelSerializer):
    class Meta:
       model = Transaction
        fields = '__all__'

ตัวซีเรียลไลเซอร์จะพิจารณาทุกคุณลักษณะที่มีอยู่ในกระเป๋าสตางค์และโมเดลธุรกรรม

ในไฟล์ wallet/views.py เราจะกำหนดฟังก์ชันมุมมองที่จำเป็นเพื่อจัดการฟังก์ชันการฝากและถอนเงินของกระเป๋าสตางค์ ฟังก์ชันเหล่านี้จะรับผิดชอบในการประมวลผลคำขอของผู้ใช้และอัปเดตข้อมูลที่เกี่ยวข้องในฐานข้อมูลตามลำดับ ด้วยการใช้มุมมองเหล่านี้ เราสามารถนำคุณสมบัติกระเป๋าสตางค์ไปใช้งานภายในแอปพลิเคชันของเราได้อย่างมีประสิทธิภาพ

 from rest_framework import generics, status
from rest_framework.response import Response
from rest_framework.decorators import action
from decimal import Decimal
from .models import Wallet, Transaction
from .serializers import WalletSerializer, TransactionSerializer

class WalletViewSet(viewsets.ModelViewSet):
   queryset = Wallet.objects.all()
   serializer_class = WalletSerializer

 @action(detail=True, methods=['post'])
   def deposit(self, request, pk=None):
       wallet = self.get_object()
       amount = Decimal(request.data['amount'])
       wallet.balance \+= amount
       wallet.save()
        serializer = WalletSerializer(wallet)
       return Response(serializer.data)
      

 @action(detail=True, methods=['post'])
   def withdraw(self, request, pk=None):
       wallet = self.get_object()
       amount = Decimal(request.data['amount'])
       if wallet.balance < amount:
           return Response({'error': 'Insufficient funds'},
                           status=status.HTTP_400_BAD_REQUEST)
       wallet.balance -= amount
       wallet.save()
       serializer = WalletSerializer(wallet)
       return Response(serializer.data)'

class TransactionViewSet(viewsets.ModelViewSet):
   queryset = Transaction.objects.all()
   Serializer_class = TransactionSerializer

เพื่อสร้าง Web Application Programming Interface (API) และระบุวิธีเข้าถึงตำแหน่งข้อมูลแต่ละจุด เราจะสร้างไฟล์ Python ใหม่ชื่อ"wallet/urls.py"ภายในโครงสร้างไดเร็กทอรีโปรเจ็กต์ของเรา ไฟล์นี้ทำหน้าที่เป็นองค์ประกอบสำคัญของสถาปัตยกรรมโดยรวม ช่วยให้สามารถสื่อสารได้อย่างราบรื่นระหว่างส่วนประกอบส่วนหน้าและบริการส่วนหลัง

 from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import WalletViewSet, TransactionViewSet, wallet_view

router = DefaultRouter()
router.register(r'wallets', WalletViewSet, basename='wallets')
router.register(r'transactions', TransactionViewSet, basename='transactions')

urlpatterns = [
   path('api/', include(router.urls)),
   path('wallets/<int:pk>/deposit/', WalletViewSet.as_view({'post': 'deposit'}),
        name='wallet-deposit'),
   path('wallets/<int:pk>/withdraw/', WalletViewSet.as_view({'post': 'withdraw'}),
        name='wallet-withdraw'),

] 

รวมรูปแบบ URL ของแอปพลิเคชันของคุณไว้ในไฟล์ theurls.py ของโปรเจ็กต์ของคุณ โดยครอบคลุมรูปแบบเหล่านั้นสำหรับแอปที่ระบุ

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

urlpatterns = [
   path('admin/', admin.site.urls),
   path('', include('wallet.urls')),
] 

เพื่อรวมฟังก์ชันการทำงานของกระเป๋าสตางค์ดิจิทัลไว้ในแอปพลิเคชันของคุณ จำเป็นต้องรวมทั้งไลบรารี “wallet” และ “rest\_framework” ภายในรายการ “INSTALLED\_APPS” ที่อยู่ภายใน “PayApp/settings.py"ไฟล์. เพื่อให้แน่ใจว่าแอปพลิเคชันเหล่านี้ได้รับการติดตั้งและรวมเข้ากับระบบโดยรวมอย่างเหมาะสม

 INSTALLED_APPS = [

"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",

"rest_framework", # new
"wallet", # new

] 

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

การใช้ API ด้วยเทมเพลต Django

ในการพัฒนาอินเทอร์เฟซที่เป็นมิตรต่อผู้ใช้สำหรับการโต้ตอบกับ API แบ็กเอนด์ของเราโดยใช้เทมเพลต Django เราจะต้องสร้างเทมเพลตใหม่ภายในโฟลเดอร์ “wallet” ที่อยู่ภายในไดเร็กทอรี “templates” เทมเพลตเฉพาะที่ต้องการมีชื่อว่า “wallet.html” และควรมีโค้ด HTML ตามมาด้านล่าง

 <!DOCTYPE html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1">
   <title>Wallet</title>
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/
   css/bootstrap.min.css">
</head>
<body>
   <div class="container">
       <h1>Wallets</h1>
       <table class="table">
           <thead>
               <tr>
                   <th>User</th>
                   <th>Balance</th>
                   <th>Actions</th>
               </tr>
           </thead>
           <tbody>
               <tr>
                   <td>{{ wallet.user }}</td>
                   <td id="balance">{{ wallet.balance }}</td>
                   <td>
                       <div id="loading-indicator" class="d-none">
                           <div class="spinner-border text-primary" role="status">
                               <span class="sr-only">Loading...</span>
                           </div>
                           <p>Please wait while the deposit is being processed.</p>
                       </div>
                       <form id="deposit-form" method="post">
                           {% csrf_token %}
                           <input type="number" name="amount" step="0.01" min="0" required>
                           <button type="submit" class="btn btn-success">Deposit</button>
                       </form>
                       <form method="post" id="withdraw-form">
                           {% csrf_token %}
                           <input type="number" name="amount" step="0.01" min="0" required>
                           <button type="submit" class="btn btn-danger">Withdraw</button>
                       </form>
                   </td>
               </tr>
           </tbody>
       </table>
   </div>

</body>
</html> 

เอกสาร HTML นำเสนออินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชันการฝากและถอนได้อย่างมีประสิทธิภาพภายในอินเทอร์เฟซผู้ใช้แบบกราฟิกที่สวยงามสวยงาม โดยใช้เฟรมเวิร์ก Bootstrap ที่ดึงดูดสายตาเพื่อวัตถุประสงค์ในการออกแบบ

การโต้ตอบของผู้ใช้กับแบบฟอร์ม

ในเอกสาร HTML ให้รวมองค์ประกอบสคริปต์และรวมเข้ากับตัวจัดการเหตุการณ์ที่เกี่ยวข้องกับเหตุการณ์การส่งแบบฟอร์มการฝากเงิน

 <script>
document.querySelector('#deposit-form').addEventListener('submit', function (event) {
           event.preventDefault();
           document.querySelector('#loading-indicator').classList.remove('d-none');
           const amount = parseFloat(document.querySelector("#deposit-form " \+
               "input[name='amount']").value);
           fetch("{% url 'wallet-deposit' wallet.id %}", {
               method: "POST",
               headers: {
                   "Content-Type": "application/json",
                   "X-CSRFToken": getCookie("csrftoken")
               },
               body: JSON.stringify({ amount: amount })
           })
               .then(response => response.json())
               .then(data => {
                   console.log(data);
                   if (data.balance !== undefined) {
                       // Convert to number and format
                       const newBalance = parseFloat(data.balance).toFixed(2);
                        document.querySelector("#balance").textContent = newBalance;
                       document.querySelector('#loading-indicator').classList.
                       add('d-none');
                   }
               })
               .catch(error => {
                   console.error("Error:", error);
                   document.querySelector('#loading-indicator')
                       .classList.add('d-none');
               });
       });
</script> 

จากนั้นให้รวมตัวฟังเหตุการณ์สำหรับการส่งแบบฟอร์มการถอนโดยใช้รหัสที่ให้ไว้ดังต่อไปนี้:

 <script>
document.querySelector('#withdraw-form').addEventListener('submit', function (event) {
   event.preventDefault();
   document.querySelector('#loading-indicator').classList.remove('d-none');
   const amount = parseFloat(document.querySelector("#withdraw-form " \+
       "input[name='amount']").value);
   fetch("{% url 'wallet-withdraw' wallet.id %}", {
       method: "POST",
       headers: {
           "Content-Type": "application/json",
           "X-CSRFToken": getCookie("csrftoken")
       },
       body: JSON.stringify({ amount: amount })
   })
       .then(response => response.json())
       .then(data => {
           console.log(data);
           if (data.balance !== undefined) { // Change to 'balance' for withdrawal
               const newBalance = parseFloat(data.balance).toFixed(2);
               document.querySelector("#balance").textContent = newBalance;
               document.querySelector('#loading-indicator').classList.add('d-none');
           }
       })
       .catch(error => {
           console.error("Error:", error);
           document.querySelector('#loading-indicator').classList.add('d-none');
       });
});
</script> 

ผู้ฟังเหตุการณ์มีหน้าที่รับผิดชอบในการจัดการการส่งแบบฟอร์มการฝากและถอนเงิน ซึ่งเชื่อมโยงกับองค์ประกอบ “#deposit-form” และ “#withdraw-form” ตามลำดับ

URL ของคำขอดึงข้อมูลสอดคล้องกับ URL ที่เกี่ยวข้องกับการดำเนินการฝากและถอนเงิน

กระบวนการนี้เกี่ยวข้องกับการแยกวิเคราะห์การตอบสนอง JSON ของธุรกรรมการฝากและถอนเงินเพื่อดึงยอดเงินในบัญชีปัจจุบัน ซึ่งต่อมาจะถูกดึงผ่านคุณสมบัติ data.balance ต่อจากนั้น ค่าเหล่านี้จะถูกแปลงและนำเสนอบนหน้าเว็บ

ในการแสดงเนื้อหาของกระเป๋าเงินดิจิทัลของผู้ใช้บนเว็บแอปพลิเคชัน จำเป็นต้องแก้ไขไฟล์ wallet/views.py โดยการรวมฟังก์ชัน render() เวอร์ชันอัปเดตที่แสดงผล wallet.html แม่แบบ. ฟังก์ชันนี้ควรคำนึงถึงการเปลี่ยนแปลงใด ๆ ที่เกิดขึ้นกับโมเดล Wallet และตรวจสอบให้แน่ใจว่าข้อมูลที่แสดงอย่างถูกต้องสะท้อนถึงสถานะปัจจุบันของกระเป๋าสตางค์ของผู้ใช้

 from django.shortcuts import render

def wallet_view(request):
   # Retrieve the wallet to display
   wallet = Wallet.objects.first()
    return render(request, 'wallet.html', {'wallet': wallet}) 

ในตัวอย่างนี้ เราจะใช้ฟังก์ชันที่เป็นประโยชน์ของเมธอด first() เพื่อเลือกพอร์ตโฟลิโอเสมือนของผู้ใช้เดี่ยวๆ เพื่อจุดประสงค์ในการสาธิตการทำงานของมัน

โปรดอัปเดตไฟล์ urls.py ในโปรเจ็กต์ของคุณโดยรวมเส้นทาง URL สำหรับ wallet\_view โดยระบุเส้นทางที่เหมาะสมดังที่แสดงด้านล่าง:

 from .views import wallet_view

urlpatterns = [
   ...
     path('home/', wallet_view, name='wallet-page'),
]

http://127.0.0.1:8000/home/

เพื่อตรวจสอบว่าการเปลี่ยนแปลงทั้งหมดนำไปใช้กับฐานข้อมูลได้สำเร็จ ขอแนะนำให้ทำตามขั้นตอนต่างๆ ประการแรก ตรวจสอบให้แน่ใจว่าได้ติดตั้งการขึ้นต่อกันที่จำเป็นโดยการรันคำสั่ง “makemigrations” ในเทอร์มินัลหรือพรอมต์คำสั่ง สิ่งนี้จะสร้างไฟล์การโยกย้ายตามการแก้ไขใด ๆ ที่ทำกับโมเดลภายในโปรเจ็กต์ จากนั้น ใช้การโยกย้ายเหล่านี้ด้วยคำสั่ง"โยกย้าย"เมื่อกระบวนการทั้งสองเสร็จสมบูรณ์โดยไม่มีข้อผิดพลาด แสดงว่าการเปลี่ยนแปลงได้รับการดำเนินการอย่างเหมาะสม สุดท้าย เปิดแอปพลิเคชัน Django โดยใช้คำสั่ง “python Manage.py runserver” ในเทอร์มินัลหรือพร้อมท์คำสั่ง ขณะนี้เซิร์ฟเวอร์ควรพร้อมใช้งานแล้ว ทำให้คุณสามารถเข้าถึงเว็บไซต์หรือบริการผ่านเว็บเบราว์เซอร์ได้

 python manage.py makemigrations
python manage.py migrate

python manage.py runserver

หากต้องการอนุญาตให้เข้าถึงปลายทางของอินเทอร์เฟซการเขียนโปรแกรมแอปพลิเคชันของเรา โปรดนำเว็บเบราว์เซอร์ของคุณไปที่ URL http://127.0.0.1:8000/api/

ผลลัพธ์ที่คาดหวัง:

/th/images/consume-django-apis-the-easy-way-with-django-templates-featured-image-wallet-api.jpeg

ไปที่ localhost เพื่อโต้ตอบกับกระเป๋าเงิน

ผลลัพธ์ที่คาดหวัง:

/th/images/consume-django-apis-the-easy-way-with-django-templates-featured-image-wallet.jpeg

กระเป๋าเงินดิจิทัลของผู้ใช้จะแสดงยอดคงเหลือในบัญชีปัจจุบัน ทำให้ผู้ใช้สามารถฝากและถอนเงินได้ตามต้องการ

ทำความเข้าใจเทมเพลต Django และบทบาทในการใช้งาน API

แม้ว่าเทมเพลต Django จะยอดเยี่ยมในการแสดงข้อมูลที่อยู่กับที่ แต่ก็มีข้อจำกัดในการผสานรวมกับ Application Programming Interfaces (API)

ระบบเทมเพลตของ Django นำเสนอระดับความสามารถในการปรับตัวที่จำกัดมากกว่าเมื่อเปรียบเทียบกับทางเลือกอื่น เช่น Jinja2 หรือ Twig นี่เป็นเพราะการพึ่งพากลยุทธ์การเรนเดอร์ที่กำหนดไว้ล่วงหน้าซึ่งจำเป็นต้องมีการจัดการด้วยตนเองเมื่อทำงานกับโครงสร้างข้อมูลที่ซับซ้อนที่ได้รับจาก API ที่ส่งข้อมูลในรูปแบบ JSON

Django ซึ่งเป็นเฟรมเวิร์กเว็บร่วมสมัยที่ใช้กันอย่างแพร่หลาย ไม่ได้ให้การสนับสนุนดั้งเดิมสำหรับการจัดการคำขอแบบอะซิงโครนัสภายในระบบเทมเพลต แม้จะมีข้อจำกัดนี้ แต่เฟรมเวิร์กสมัยใหม่อื่นๆ เช่น Flask ก็นำการใช้ไวยากรณ์ async/await มาใช้ในกระบวนการพัฒนา ด้วยเหตุนี้ เมื่อใช้เครื่องมือเทมเพลตของ Django จำเป็นต้องดำเนินการคำขอทั้งหมดตามลำดับก่อนที่จะเรนเดอร์หน้าเว็บ แม้ว่าจะต้องมีแหล่งข้อมูลหลายแหล่งเพื่อสร้างเนื้อหาก็ตาม

เทมเพลต Django ขาดกลไกตามธรรมชาติในการรองรับข้อผิดพลาดที่อาจเกิดขึ้นจากการใช้งาน API ไม่ใช่เรื่องแปลกที่ข้อยกเว้นจะเกิดขึ้นระหว่างการดำเนินการดังกล่าว โดยจำเป็นต้องมีการแทรกแซงด้วยตนเองเพื่อจัดการกับข้อยกเว้นภายในขอบเขตของเทมเพลต ซึ่งอาจนำไปสู่โค้ดที่ยุ่งยากและบำรุงรักษายาก

สร้างแอปพลิเคชันที่ปรับขนาดได้

เทมเพลต Django อำนวยความสะดวกในการแยกเลเยอร์การนำเสนอออกจากตรรกะทางธุรกิจ ช่วยให้นักพัฒนามีสมาธิกับการเขียนโค้ดที่นำมาใช้ซ้ำได้และยั่งยืน อย่างไรก็ตาม ด้วยข้อจำกัด เทมเพลต Django อาจไม่เหมาะสมที่สุดสำหรับการจัดการ API ในขนาดที่กว้างขวาง ในสถานการณ์เช่นนี้ กรอบงานไคลเอนต์เช่น React ยังคงมีความเกี่ยวข้องในการสร้างระบบซอฟต์แวร์ที่ปรับขนาดได้