Contents

Korzystaj z API Django w prosty sposób dzięki szablonom Django

Gdy używasz technologii backendowej lub frameworka takiego jak Django, Laravel lub Node.js do pisania API REST, musisz mieć dodatkowe umiejętności frontendowe używając frameworków takich jak React, Angular i Vue, aby konsumować punkty końcowe API. Ale nie zawsze tak jest, możesz konsumować API w samym Django używając szablonów Django.

Konfigurowanie projektu Django i punktów końcowych API

Rozpoczynając proces, zaczniemy od utworzenia folderu projektu w naszym systemie plików. Korzystając z aplikacji Terminal, przejdź do żądanej lokalizacji i wygeneruj nowy katalog, który posłuży jako centrum organizacyjne dla twojego przedsięwzięcia.

 mkdir payment_wallet_project
cd payment_wallet_project 

Aby postępować zgodnie z tym przewodnikiem instruktażowym, będziesz konstruował interfejsy programowania aplikacji (API) przeznaczone do użytku w połączeniu z portfelem cyfrowym wykorzystywanym do transakcji finansowych.

Dostęp do pełnego kodu źródłowego można uzyskać za pośrednictwem repozytorium GitHub, które jest łatwo dostępne dla odniesienia i dalszej eksploracji.

Na początek należy utworzyć wirtualne środowisko wykorzystujące bibliotekę Pipenv jako podstawę kontekstu rozwoju naszego projektu.

 pipenv install django djangorestframework 

Wykonanie tej instrukcji spowoduje instalację wymaganych bibliotek i utworzenie środowiska wirtualnego.

Aby aktywować środowisko wirtualne, wykonaj następujące polecenie w terminalu lub wierszu polecenia:bashsource /venv/bin/activateZastąp rzeczywistą ścieżką do katalogu projektu na komputerze. Spowoduje to aktywację środowiska wirtualnego i umożliwi korzystanie z zainstalowanych w nim pakietów dla skryptu Python.

 pipenv shell

Aby utworzyć nowy projekt Django, przejdź do preferowanego katalogu i wykonaj polecenie “django-admin startproject PayApp”. To zainicjuje utworzenie nowego projektu o nazwie “PayApp” we wskazanej lokalizacji.

 django-admin startproject PayApp . 

Użycie końcowego znaku interpunkcyjnego (. https://en.wikipedia.org/wiki/. ) po komendzie “django-admin” minimalizuje prawdopodobieństwo zduplikowanej replikacji podstawowej struktury folderów projektu w nowo utworzonej aplikacji Django.

Aby utworzyć nową aplikację Django w istniejącym katalogu projektu, wykonaj następujące kroki:1. Otwórz terminal i przejdź do głównego folderu projektu Django za pomocą polecenia cd .2. Gdy znajdziesz się we właściwym katalogu, uruchom następujące polecenie, aby utworzyć nową aplikację Django o nazwie “myapp”:bashpython manage.py startapp myapp3.Spowoduje to wygenerowanie nowego katalogu o nazwie “myapp” wewnątrz katalogu “apps” w twoim projekcie Django. Wewnątrz tego katalogu znajdziesz kilka plików, które tworzą podstawową strukturę twojej nowej aplikacji.

 python manage.py startapp wallet 

Aby rozpocząć tworzenie aplikacji API, postępuj zgodnie z wytycznymi przedstawionymi

Creating a Payment Wallet REST API

Aby zaimplementować kompleksowy backend dla twojej aplikacji kryptowalutowej, niezbędne jest otwarcie pliku wallet/models.py w twoim projekcie Django i stworzenie dwóch oddzielnych modeli dla portfela i transakcji. Modele te posłużą jako podstawa schematu bazy danych i zapewnią niezbędną strukturę do przechowywania i pobierania danych związanych z kontami użytkowników i transakcjami w systemie.

 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) 

Aby utworzyć nowy plik w katalogu portfela, zatytułowany “serializers.py”, przystąpimy do generowania zestawu serializerów zarówno dla modelu portfela, jak i transakcji. Ułatwi to efektywne zarządzanie danymi i ich organizację w systemie zaplecza naszej aplikacji.

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

Serializatory uwzględniają każdy atrybut obecny zarówno w schemacie portfela, jak i modelu transakcji.

W pliku wallet/views.py zdefiniujemy niezbędne funkcje widoku do obsługi funkcji wpłat i wypłat portfela. Funkcje te będą odpowiedzialne za przetwarzanie żądań użytkowników i odpowiednią aktualizację danych w bazie danych. Implementując te widoki, możemy skutecznie wdrożyć funkcję portfela w naszej aplikacji.

 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

Aby ustanowić interfejs programowania aplikacji internetowych (API) i określić sposób dostępu do każdego punktu końcowego, utworzymy nowy plik Pythona o nazwie “wallet/urls.py” w strukturze katalogów naszego projektu. Plik ten służy jako istotny element ogólnej architektury, umożliwiając płynną komunikację między komponentami front-end i usługami back-end.

 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'),

] 

Włącz wzorce adresów URL aplikacji do plikuurls.py projektu, obejmując te dla określonej aplikacji.

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

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

Aby włączyć funkcjonalność portfela cyfrowego do swojej aplikacji, konieczne jest dołączenie zarówno bibliotek “wallet”, jak i “rest\_framework” do listy “INSTALLED\_APPS” znajdującej się w pliku “PayApp/settings.py”. Zapewni to prawidłową instalację i integrację tych aplikacji z całym systemem.

 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

] 

Rejestracja aplikacji wallet i rest\_framework w rejestrze aplikacji projektu Django jest procesem, który umożliwia wykorzystanie tych modułów w szerszym kontekście projektu, zwiększając ich funkcjonalność poprzez wykorzystanie zasobów dostarczanych przez framework Django.

Korzystanie z API za pomocą szablonów Django

Aby opracować przyjazny dla użytkownika interfejs do interakcji z naszym backendowym API za pomocą szablonów Django, będziemy musieli utworzyć nowy szablon w folderze “wallet” znajdującym się w katalogu “templates”. Konkretny wymagany szablon nosi nazwę “wallet.html” i powinien zawierać poniższy kod 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> 

Dokument HTML skutecznie prezentuje interfejsy programowania aplikacji do wpłat i wypłat w estetycznym graficznym interfejsie użytkownika, wykorzystując atrakcyjny wizualnie framework Bootstrap do celów projektowych.

Interakcja użytkownika z formularzami

W dokumencie HTML należy uwzględnić element skryptu i zintegrować go z programem obsługi zdarzeń powiązanym ze zdarzeniem przesłania formularza wpłaty.

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

Następnie włącz detektor zdarzeń dla wysłania formularza wypłaty, wykorzystując dostarczony kod w następujący sposób:

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

Słuchacz zdarzeń jest odpowiedzialny za zarządzanie przesyłaniem formularzy wpłaty i wypłaty, które są powiązane odpowiednio z elementami “#deposit-form” i “#withdraw-form”.

Adres URL żądania pobrania odpowiada adresom URL powiązanym z akcjami wpłaty i wypłaty.

Proces obejmuje analizowanie odpowiedzi JSON zarówno transakcji wpłaty, jak i wypłaty w celu pobrania bieżącego salda konta, które jest następnie pobierane za pośrednictwem właściwości data.balance . Następnie wartości te są przekształcane i prezentowane na stronie internetowej.

Aby wyświetlić zawartość cyfrowego portfela użytkownika w aplikacji internetowej, konieczne jest zmodyfikowanie pliku wallet/views.py poprzez włączenie zaktualizowanej wersji funkcji render() , która renderuje szablon wallet.html . Funkcja ta powinna uwzględniać wszelkie zmiany wprowadzone w modelu Wallet i zapewniać, że wyświetlane informacje dokładnie odzwierciedlają aktualny stan portfela użytkownika.

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

W tym przykładzie wykorzystamy funkcjonalność metody first() do wybrania wirtualnego portfela pojedynczego użytkownika w celu zademonstrowania jej działania.

Prosimy o aktualizację pliku urls.py w projekcie poprzez włączenie trasy URL dla wallet_view , określając odpowiednią ścieżkę, jak pokazano poniżej:

 from .views import wallet_view

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

" http://127.0.0.1:8000/home/ “.

Aby sprawdzić, czy wszystkie zmiany zostały pomyślnie zastosowane w bazie danych, zaleca się wykonanie szeregu czynności. Po pierwsze, upewnij się, że niezbędne zależności są zainstalowane, uruchamiając polecenie “makemigrations” w terminalu lub wierszu polecenia. Spowoduje to wygenerowanie plików migracji na podstawie wszelkich modyfikacji dokonanych w modelach w ramach projektu. Następnie należy zastosować te migracje za pomocą polecenia “migrate”. Gdy oba procesy zakończą się bez błędów, oznacza to, że zmiany zostały poprawnie zaimplementowane. Na koniec uruchom aplikację Django za pomocą polecenia “python manage.py runserver” w terminalu lub wierszu poleceń. Serwer powinien być teraz gotowy do użycia, umożliwiając dostęp do strony internetowej lub usługi za pośrednictwem przeglądarki internetowej.

 python manage.py makemigrations
python manage.py migrate

python manage.py runserver

Aby uzyskać dostęp do punktów docelowych naszego interfejsu programowania aplikacji, należy skierować przeglądarkę internetową na adres URL http://127.0.0.1:8000/api/ .

Oczekiwany wynik:

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

Przejdź do localhost , aby wejść w interakcję z portfelem.

Oczekiwane dane wyjściowe:

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

Cyfrowy portfel użytkownika wyświetla bieżące saldo konta, zapewniając mu wygodny sposób inicjowania zarówno wpłat, jak i wypłat w razie potrzeby.

Understanding Django Templates and Their Role in API Consumption

Chociaż szablony Django doskonale sprawdzają się w prezentowaniu stacjonarnych danych, podlegają ograniczeniom, jeśli chodzi o integrację z interfejsami programowania aplikacji (API).

System szablonów Django oferuje bardziej ograniczony poziom adaptowalności w porównaniu do innych alternatyw, takich jak Jinja2 czy Twig. Wynika to z polegania na predefiniowanych strategiach renderowania, które wymagają ręcznej manipulacji podczas pracy ze złożonymi strukturami danych uzyskanymi z interfejsów API dostarczających informacje w formacie JSON.

Django, szeroko stosowany współczesny framework webowy, nie zapewnia natywnego wsparcia dla obsługi asynchronicznych żądań w swoim systemie szablonów. Pomimo tego ograniczenia, inne nowoczesne frameworki, takie jak Flask, przyjęły składnię async/await w swoim procesie rozwoju.W rezultacie, podczas korzystania z silnika szablonów Django, konieczne jest sekwencyjne wykonywanie wszystkich żądań przed renderowaniem strony internetowej, nawet jeśli do generowania treści wymaganych jest wiele źródeł danych.

Szablonom Django brakuje naturalnego mechanizmu uwzględniania błędów, które mogą wynikać z użycia API. Nierzadko zdarza się, że podczas takich operacji rzucane są wyjątki, co wymaga ręcznej interwencji w celu ich obsługi w ramach szablonu. Może to prowadzić do uciążliwego i trudnego w utrzymaniu kodu.

Budowanie skalowalnych aplikacji

Szablony Django ułatwiają oddzielenie warstw prezentacji od logiki biznesowej, umożliwiając programistom skoncentrowanie się na tworzeniu kodu wielokrotnego użytku i zrównoważonego. Niemniej jednak, biorąc pod uwagę ich ograniczenia, szablony Django mogą nie być optymalne do obsługi API na dużą skalę. W takich sytuacjach frameworki klienckie, takie jak React, nadal są istotne w tworzeniu skalowalnych systemów oprogramowania.