Contents

Använd Django API:er på ett enkelt sätt med Django-mallar

När man använder en backend-teknik eller ett ramverk som Django, Laravel eller Node.js för att skriva REST API:er, måste man ha ytterligare frontend-kompetens med ramverk som React, Angular och Vue för att konsumera API-slutpunkterna. Men det är inte alltid fallet, du kan konsumera API:erna i Django själv med hjälp av Django-mallar.

Ställa in ett Django-projekt och API-slutpunkter

Genom att initiera processen ska vi börja med att skapa en projektmapp i vårt filsystem. Använd Terminal-applikationen för att navigera till önskad plats och skapa en ny katalog som ska fungera som ett organisatoriskt nav för ditt projekt.

 mkdir payment_wallet_project
cd payment_wallet_project 

För att följa den här instruktionsguiden kommer du att konstruera API:er (Application Programming Interface) som är avsedda att användas i samband med en digital plånbok som används för finansiella transaktioner.

Den fullständiga källkoden kan nås via ett GitHub-arkiv, som är lättillgängligt för referens och vidare utforskning.

Börja med att skapa en virtuell miljö med Pipenv-biblioteket som grund för vårt projekts utvecklingskontext.

 pipenv install django djangorestframework 

Genomförandet av denna instruktion kommer att resultera i installationen av nödvändiga bibliotek och upprättandet av en virtuell miljö.

För att aktivera en virtuell miljö, utför följande kommando i din terminal eller kommandotolk:bashsource /venv/bin/activateErsätt med den faktiska sökvägen till din projektkatalog på din dator. Detta kommer att aktivera den virtuella miljön och låta dig använda alla paket som är installerade i den för ditt Python-skript.

 pipenv shell

För att skapa ett nytt Django-projekt, navigera till din önskade katalog och kör kommandot “django-admin startproject PayApp”. Detta kommer att initiera skapandet av ett nytt projekt som heter “PayApp” på den angivna platsen.

 django-admin startproject PayApp . 

Genom att använda det avslutande skiljetecknet (. https://en.wikipedia.org/wiki/. ) efter kommandot “django-admin” minimeras sannolikheten för en duplicerad replikering av projektets primära mappstruktur i den nyskapade Django-applikationen.

Gör så här för att skapa en ny Django-applikation i den befintliga projektkatalogen:1. Öppna terminalen och navigera till rotmappen för ditt Django-projekt med kommandot cd .2. När du är i rätt katalog kör du följande kommando för att skapa en ny Django-applikation som heter “myapp”:bashpython manage.py startapp myapp3.Detta kommer att generera en ny katalog som heter “myapp” i “apps”-katalogen i ditt Django-projekt. I den här katalogen hittar du flera filer som utgör den grundläggande strukturen för din nya app.

 python manage.py startapp wallet 

För att börja bygga din API-applikation, vänligen följ de riktlinjer som beskrivs

Skapa en Payment Wallet REST API

För att implementera en omfattande backend för din kryptovalutaapplikation är det viktigt att öppna wallet/models.py filen i ditt Django-projekt och skapa två separata modeller för plånboken och transaktionerna. Dessa modeller kommer att fungera som grunden för ditt databasschema och ge den nödvändiga strukturen för lagring och hämtning av data relaterade till användarkonton och transaktioner inom systemet.

 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) 

För att skapa en ny fil i wallet-katalogen, med titeln “serializers.py”, ska vi fortsätta med att generera en uppsättning serializers för både wallet- och transaktionsmodellerna. Detta kommer att underlätta effektiv datahantering och organisation inom vår applikations backend-system.

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

Serialiserarna tar hänsyn till varje attribut som finns i både plånbokens och transaktionsmodellens scheman.

I filen wallet/views.py kommer vi att definiera de nödvändiga vyfunktionerna för att hantera plånbokens insättnings- och uttagsfunktioner. Dessa funktioner kommer att ansvara för att behandla användarförfrågningar och uppdatera relevanta data i databasen i enlighet med detta. Genom att implementera dessa vyer kan vi effektivt implementera plånboksfunktionen i vår applikation.

 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

För att etablera programmeringsgränssnittet (API) för webbapplikationer och specificera hur varje ändpunkt ska nås skapar vi en ny Python-fil med namnet “wallet/urls.py” i vår projektkatalogstruktur. Denna fil är en viktig komponent i den övergripande arkitekturen och möjliggör sömlös kommunikation mellan front-end-komponenterna och back-end-tjänsterna.

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

] 

Införliva URL-mönstren för din applikation i filenurls.py i ditt projekt, och inkludera dem för den angivna appen.

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

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

För att kunna införliva funktionaliteten hos en digital plånbok i din applikation är det nödvändigt att inkludera både “wallet” och “rest\_framework” biblioteken i “INSTALLED\_APPS” listan som finns i “PayApp/settings.py” filen. Detta säkerställer att dessa applikationer är korrekt installerade och integrerade med det övergripande systemet.

 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

] 

Registrering av applikationerna wallet och rest\_framework i Django-projektets applikationsregister är en process som gör att dessa moduler kan användas inom projektets bredare sammanhang och förbättra deras funktionalitet genom att utnyttja de resurser som tillhandahålls av Django-ramverket.

Använda API med Django-mallar

För att utveckla ett användarvänligt gränssnitt för att interagera med vårt backend-API med hjälp av Django-mallar måste vi skapa en ny mall i mappen “wallet” som finns i katalogen “templates”. Den specifika mall som krävs heter “wallet.html”, och den ska innehålla den efterföljande HTML-koden som anges nedan.

 <!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-dokumentet presenterar effektivt programmeringsgränssnitten för insättning och uttag i ett estetiskt tilltalande grafiskt användargränssnitt, med hjälp av det visuellt tilltalande Bootstrap-ramverket för designändamål.

Användarinteraktion med formulär

I HTML-dokumentet ska du införliva ett skriptelement och integrera det i händelsehanteraren som är kopplad till insättningsformulärets inlämningshändelse.

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

Integrera därefter händelsehanteraren för uttagsformulärets inlämning med hjälp av den medföljande koden enligt följande:

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

Händelselyssnaren är ansvarig för att hantera inlämningen av insättnings- och uttagsformulären, som är associerade med elementen “#deposit-form” respektive “#withdraw-form”.

URL:en i hämtningsförfrågan motsvarar de URL:er som är kopplade till insättnings- och uttagsåtgärder.

Processen innebär att JSON-svaren från både insättnings- och uttagstransaktioner analyseras för att hämta det aktuella kontosaldot, som därefter hämtas via egenskapen data.balance . Därefter transformeras dessa värden och presenteras på webbsidan.

För att kunna visa innehållet i en användares digitala plånbok på webbapplikationen är det nödvändigt att modifiera filen wallet/views.py genom att införliva en uppdaterad version av funktionen render() som renderar mallen wallet.html . Denna funktion bör ta hänsyn till alla ändringar som gjorts i Wallet modellen och säkerställa att den information som visas korrekt återspeglar den aktuella statusen för användarens plånbok.

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

I detta illustrativa fall ska vi använda den utilitaristiska funktionen i metoden first() för att välja en ensam användares virtuella portfölj i syfte att demonstrera dess funktion.

Vänligen uppdatera filen urls.py i ditt projekt genom att införliva en URL-väg för wallet_view och ange lämplig sökväg enligt nedan:

 from .views import wallet_view

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

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

För att kontrollera att alla ändringar har överförts till databasen rekommenderar vi att du utför en rad steg. Kontrollera först att de nödvändiga beroendena är installerade genom att köra kommandot “makemigrations” i terminalen eller kommandotolken. Detta kommer att generera migreringsfiler baserat på eventuella ändringar som gjorts i modellerna inom projektet. Tillämpa sedan dessa migreringar med kommandot “migrate”. När båda processerna har slutförts utan fel indikerar detta att ändringarna har implementerats korrekt. Slutligen startar du Django-applikationen med kommandot “python manage.py runserver” i terminalen eller kommandotolken. Servern bör nu vara klar för användning, så att du kan komma åt webbplatsen eller tjänsten via en webbläsare.

 python manage.py makemigrations
python manage.py migrate

python manage.py runserver

För att få tillgång till vårt applikationsprogrammeringsgränssnitts slutpunktsdestinationer, vänligen rikta din webbläsare till URL http://127.0.0.1:8000/api/ .

Förväntat resultat:

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

Navigera till localhost för att interagera med plånboken.

Förväntat resultat:

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

Användarens digitala plånbok visar det aktuella kontosaldot, vilket ger användaren ett bekvämt sätt att initiera både insättningar och uttag efter behov.

Förstå Django-mallar och deras roll i API-konsumtion

Även om Django-mallar är utmärkta för att visa stationära data har de begränsningar när det gäller att integrera med API:er (Application Programming Interfaces).

Djangos mallsystem erbjuder en mer begränsad nivå av anpassningsförmåga jämfört med andra alternativ som Jinja2 eller Twig. Detta beror på dess beroende av fördefinierade renderingsstrategier som kräver manuell manipulation när man arbetar med komplexa datastrukturer som erhållits från API: er som levererar JSON-formaterad information.

Django, ett allmänt använt modernt webbramverk, har inget inbyggt stöd för att hantera asynkrona förfrågningar i sitt mallsystem. Trots denna begränsning har andra moderna ramverk som Flask börjat använda async/await-syntax i sin utvecklingsprocess.När Djangos mallmotor används är det därför nödvändigt att slutföra alla förfrågningar sekventiellt innan en webbsida renderas, även om flera datakällor krävs för att generera innehåll.

Djangos mallar saknar en naturlig mekanism för att hantera fel som kan uppstå vid API-användning. Det är inte ovanligt att undantag kastas under sådana operationer, vilket kräver manuellt ingripande för att hantera dem inom mallens gränser. Detta kan leda till tungrodd kod som är svår att underhålla.

Bygg skalbara applikationer

Djangos mallar gör det lättare att separera presentationslager från affärslogik, så att utvecklarna kan koncentrera sig på att komponera återanvändbar och hållbar kod. Med tanke på deras begränsningar är Django-mallar dock kanske inte optimala för hantering av API:er i stora skalor. I sådana situationer fortsätter klientramverk som React att vara relevanta för att konstruera skalbara programvarusystem.