Django, Laravel 또는 Node.js와 같은 백엔드 기술이나 프레임워크를 사용하여 REST API를 작성하는 경우 API 엔드포인트를 사용하려면 React, Angular, Vue와 같은 프레임워크를 사용하는 추가적인 프론트엔드 기술이 필요합니다. 하지만 항상 그런 것은 아니며, 장고 템플릿을 사용하여 장고 자체에서 API를 사용할 수 있습니다.

장고 프로젝트 및 API 엔드포인트 설정하기

프로세스를 시작하기 위해 터미널 환경 내에 디렉터리를 생성하는 방식으로 프로젝트 작업 공간을 설정해야 합니다. 파일 시스템에서 원하는 위치로 이동하여 적절한 명령줄 구문을 사용하여 이 지정된 영역을 작업의 기초로 인스턴스화하세요.

 mkdir payment_wallet_project
cd payment_wallet_project

디지털 결제 지갑의 API 개발에 대한 포괄적인 이해를 구축하기 위해서는 다양한 소프트웨어 구성 요소를 탐색하고 조작하는 동시에 애플리케이션 프레임워크 내에서 효과적으로 통합하는 것이 필수적입니다. 이 과정에는 민감한 사용자 정보를 보호하기 위한 보안 조치를 구현하고 사용자와 저장된 자금 간의 원활한 상호 작용을 가능하게 하는 직관적인 인터페이스를 설계하는 것이 포함됩니다. 또한 업계에서 일반적으로 사용되는 NodeJS 또는 Python과 같은 관련 프로그래밍 언어 및 프레임워크에 대한 철저한 지식이 필요합니다. 이러한 API를 개발할 때는 PayPal이나 Stripe과 같은 선도 기업이 제시하는 모범 사례와 표준을 준수하여 기존 시스템과의 호환성을 보장하고 잠재 사용자 간의 신뢰를 구축하는 것이 중요합니다. 강력하고 안전한 API를 구축하면 디지털 환경에서 결제를 관리하고 전송하는 효율적인 수단을 제공할 수 있습니다.

전체 코드베이스는 모든 콘텐츠와 기능에 액세스할 수 있는 GitHub 리포지토리를 통해 액세스할 수 있습니다.

프로젝트 설정 프로세스를 시작하기 위해 다양한 프로젝트를 위한 가상 환경의 생성 및 배포를 간소화하고 효율화하도록 설계된 Python 가상 환경 관리 도구인 Pipenv를 활용합니다.

 pipenv install django djangorestframework 

이 명령어를 실행하면 필요한 라이브러리가 설치되고 가상 환경이 설정됩니다.

가상 환경을 활성화하려면 Python 인터프리터의 설명서 또는 패키지 관리 시스템에 제공된 명령을 사용할 수 있습니다. 일반적으로 가상 환경이 포함된 디렉터리 경로와 필요한 플래그 또는 옵션을 지정하는 명령을 입력합니다. 이 명령이 실행되면 컴퓨터에 설치된 다른 패키지의 간섭 없이 패키지를 설치하고 Python 코드를 실행할 수 있는 가상 환경의 활성 인스턴스가 생성됩니다.

 pipenv shell

PayApp이라는 이름의 새로운 Django 프로젝트를 설정합니다.

 django-admin startproject PayApp . 

django-admin 명령을 종료할 때 마침표(.)를 사용하면 프로젝트가 자체 디렉터리의 부적절한 복제를 생성할 가능성을 완화하여 프로젝트 구조 내에서 체계적인 조직과 효율성을 유지하는 데 기여할 수 있습니다.

프로젝트의 디렉토리 구조 내에서 더 큰 시스템의 독립적인 구성 요소로 작동할 새로운 Django 애플리케이션을 설정합니다.

 python manage.py startapp wallet 

앞서 언급한 지침을 활용하여 후속 프로토콜을 준수하여 API 애플리케이션을 구축하세요.

결제 지갑 REST API 생성하기

`wallets/models.py` 파일을 열고 사용자\_id, 잔액, 주소 등의 속성을 포함하는 지갑 모델에 대한 새 클래스를 생성하세요. 또한 발신자\_주소, 수신자\_주소, 금액, 타임스탬프와 같은 속성을 포함하는 트랜잭션 모델에 대한 또 다른 클래스를 생성합니다.

 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__'

직렬화기는 지갑과 트랜잭션 모델 계층 구조에 존재하는 모든 속성을 고려합니다.

이 글도 확인해 보세요:  파이썬을 사용하여 FLAMES 게임 플레이하기

`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

암호화폐 거래소 웹 애플리케이션의 API에 대한 URL 라우팅을 설정하기 위해 장고 프로젝트 디렉토리에 `wallet/urls.py`라는 새 파일을 생성합니다. 이 파일은 들어오는 HTTP 요청이 어떻게 처리되고 API 내의 특정 뷰로 라우팅되는지 정의하는 역할을 담당합니다. 이를 통해 사용자는 GET, POST, PUT, DELETE 등과 같은 표준 메서드를 사용하여 다양한 엔드포인트를 통해 시스템과 상호 작용할 수 있으며, 데이터에 액세스하거나 디지털 자산을 대신하여 작업을 수행할 수 있는 직관적인 방법을 제공할 수 있습니다.

 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 구성에 애플리케이션의 기능을 적절히 통합하기 위해서는 해당 앱과 관련된 관련 URL을 각각의 urls.py 파일에 포함시켜야 합니다.이렇게 하면 이러한 특정 엔드포인트에 대한 모든 요청이 애플리케이션 내의 적절한 뷰에 의해 적절하게 라우팅되고 처리됩니다.

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

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

실제로 PayApp 프로젝트에 지갑 및 REST 프레임워크 애플리케이션을 통합하려면 settings.py 파일에 지정된 대로 설치된 애플리케이션 목록에 해당 애플리케이션을 포함시켜야 합니다. 이는 기존 INSTALLED\_APPS 목록에 해당 앱 이름을 추가하기만 하면 됩니다.

 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

]

이 과정을 통해 장고 프로젝트의 애플리케이션 내에 지갑 앱과 Rest 프레임워크 모듈을 모두 등록할 수 있습니다.

장고 템플릿으로 API 사용

API에 액세스하기 위한 사용자 친화적인 인터페이스를 개발하기 위해 장고 템플릿을 활용하여 간소화된 프런트엔드를 만들 것입니다. 이 작업을 수행하려면 ‘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 파일은 부트스트랩 프레임워크를 활용하여 개발한 미적으로 보기 좋은 그래픽 사용자 인터페이스를 통해 입출금 애플리케이션 프로그래밍 인터페이스를 표시합니다.

이 글도 확인해 보세요:  웹 개발을 위한 가장 인기 있는 8가지 백엔드 프레임워크

양식과 사용자 상호 작용

예! 다음은 이를 자바스크립트로 구현하는 방법의 예입니다: ”’자바스크립트 // 입금 양식 요소 가져오기 const depositForm = document.getElementById(‘deposit-form’); // 양식 제출 시 이벤트 리스너를 추가합니다. depositForm.addEventListener(‘submit’, function(event) { // 이벤트 리스너 추가 // 양식을 제출하는 기본 동작(예: 새 페이지로 이동)을 방지합니다. event.preventDefault(); // 계정 잔액을 기준으로 환자가 지불해야 하는 금액으로 결제 요청을 생성합니다. const request = new PaymentRequest({ 금액: { total: parseFloat(document.getElementById(‘account-balance’).innerHTML), currency: ‘USD’ },

 <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>

이벤트 리스너는 웹사이트의 “#입금-양식” 및 “#출금-양식” 요소와 관련하여 입금 및 출금 양식 제출 처리를 관리할 책임을 지게 됩니다.

가져오기 요청에 사용된 URL(유니폼 리소스 로케이터)은 입금 및 출금 작업과 관련된 URL과 일치해야 합니다.

입출금 거래 모두에 대한 JSON 데이터가 검색되면 현재 계좌 잔액(‘data.balance’라고 함)을 얻기 위해 처리됩니다. 이후 이 정보는 구조화되어 시각적으로 보기 좋은 방식으로 웹페이지에 표시됩니다.

`wallet.html` 템플릿에 포함된 정보를 표시하려면 이 특정 페이지를 렌더링하는 메서드를 추가하여 `wallet/views.py` 파일을 수정해야 합니다. 이 작업은 적절한 컨텍스트 변수와 템플릿 이름을 인수로 전달하는 Django의 `render()` 모듈의 인스턴스를 통해 수행할 수 있습니다. 업데이트된 코드는 다음과 같습니다: “`python 에서 django.shortcuts import render def wallet(request): # 지갑 데이터를 생성하는 로직은 다음과 같습니다… # 지갑 데이터를 키와 해당 값으로 포함하는 사전을 생성합니다. wallet_data = {‘key1’: ‘value1’, ‘key2’: ‘value2’} # 지갑 전달

 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})

예시를 위해 이 예제에서는 단독 사용자의 디지털 지갑을 선택하기 위해 첫 번째() 쿼리 방법을 사용하겠습니다.

이 글도 확인해 보세요:  녹 매크로: 매크로를 사용하여 코드를 개선하는 방법

언어를 개선하기 위해 주어진 구문을 다음과 같은 방식으로 바꾸면 좋습니다: “적절한 URL 경로를 포함하는 ‘wallet\_view’의 경로를 통합하여 urls.py 파일을 수정합니다.

 from .views import wallet_view

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

브라우저에서 에 있는 웹 주소를 사용하여 지갑 페이지로 이동하세요.

모든 구성 요소가 올바르게 작동하면 ‘makemigrations’ 명령과 ‘migrate’ 명령을 차례로 실행하여 마이그레이션 프로세스를 시작하세요. 그런 다음 애플리케이션을 실행하여 사용하세요.

 python manage.py makemigrations
python manage.py migrate

python manage.py runserver

애플리케이션 프로그래밍 인터페이스(API) 엔드포인트에 액세스하려면 웹 브라우저에서 로 이동하세요.

주어진 텍스트에는 개인이 어떤 일을 하도록 요청받았지만 요청에 따르고 싶지 않은 상황에 대한 설명이 포함되어 있습니다. 화자는 거부 의사를 표현하고 특정 조건이 충족될 경우에만 동의하겠다고 말합니다. 또한 다른 사람의 행동으로 인해 이러한 결정을 내릴 수밖에 없었음을 나타냅니다.

로컬호스트 로 이동하여 지갑과 상호 작용합니다.

이 백서의 저자들은 주의 메커니즘을 통해 환경 구조에 대한 사전 지식을 통합하여 강화 학습 알고리즘의 성능을 최적화하는 새로운 접근 방식을 제안했습니다. “주의 기반 우선순위 지정”이라고 하는 이 방법은 까다로운 환경에서 에이전트의 탐색을 향상시키고 전반적인 학습 효율성을 개선합니다. 이 연구에서 제시된 결과는 주의 기반 우선순위 지정이 시각적 탐색, 연속 제어, 의사 결정 문제 등 다양한 수준의 복잡성을 가진 다양한 작업에서 최첨단 RL 알고리즘의 성능을 크게 향상시킬 수 있음을 보여줍니다.또한, 저자들은 이러한 접근 방식이 RL을 넘어 다른 영역으로 확장되어 다양한 머신러닝 애플리케이션에 잠재적으로 도움이 될 수 있다고 제안합니다.

지갑은 입금 또는 출금 거래를 시작할 수 있는 기능과 함께 현재 계좌 잔액을 표시합니다.

장고 템플릿의 이해와 API 소비에서의 역할

장고 템플릿은 정적 콘텐츠를 표시하는 데는 탁월하지만 API를 효과적으로 활용하는 데는 제한이 있습니다.

Django의 템플릿 시스템은 Jinja2나 Twig와 같은 다른 옵션과 비교할 때 경직성이 높은 것으로 알려져 있습니다. 그 이유는 사전 정의된 레이아웃에 특별히 적합하기 때문입니다. 따라서 API에서 검색된 복잡한 데이터를 JSON 형식으로 처리하려면 템플릿 내의 정보를 수동으로 조작해야 합니다. 그러나 이러한 작업을 처리하는 것은 특히 수신된 데이터의 구조가 정교한 경우 힘든 작업이 될 수 있습니다.

장고 템플릿은 비동기 요청을 처리할 수 없으며, 이는 플라스크나 장고와 같은 프레임워크가 비동기 구문을 지원하는 최신 웹 개발 관행에 반하는 것입니다. 이러한 제한에도 불구하고 장고 템플릿은 동기 처리가 필요하므로 웹페이지를 렌더링하기 위해 여러 소스에서 데이터를 가져오기 전에 실행을 완료해야 합니다.

장고 템플릿에는 API를 사용할 때 발생할 수 있는 오류를 처리하는 정교한 시스템이 부족합니다. API 요청이 실패할 경우 템플릿 내에서 이러한 예외를 원활하게 관리할 수 있는 고유한 메커니즘이 없습니다. 따라서 예외를 캡처하여 템플릿 내에서 직접 처리해야 하므로 코드가 번거롭고 유지 관리가 어렵습니다.

확장 가능한 애플리케이션 빌드

장고 템플릿은 애플리케이션의 디스플레이 측면을 핵심 기능으로부터 분리하는 수단을 제공하므로 프로그래머는 모듈식의 강력한 코드를 작성하는 데 집중할 수 있습니다. 그럼에도 불구하고 이러한 템플릿의 특정 제약으로 인해 대량의 데이터를 처리하는 데 적합하지 않을 수 있으므로 React와 같은 클라이언트 측 프레임워크와 같은 대체 접근 방식이 필요할 수 있습니다.

By 김민수

안드로이드, 서버 개발을 시작으로 여러 분야를 넘나들고 있는 풀스택(Full-stack) 개발자입니다. 오픈소스 기술과 혁신에 큰 관심을 가지고 있고, 보다 많은 사람이 기술을 통해 꿈꾸던 일을 실현하도록 돕기를 희망하고 있습니다.