Contents

Consuma APIs Django de maneira fácil com modelos Django

Ao usar uma tecnologia de backend ou framework como Django, Laravel ou Node.js para escrever APIs REST, você precisa ter uma habilidade adicional de frontend usando frameworks como React, Angular e Vue para consumir os endpoints da API. Mas isso nem sempre é o caso, você pode consumir as APIs no próprio Django usando modelos Django.

Configurando um projeto Django e endpoints de API

Iniciando o processo, vamos começar estabelecendo uma pasta de projeto dentro do nosso sistema de arquivos. Utilizando o aplicativo Terminal, navegue até o local desejado e gere um novo diretório para servir como um centro organizacional para o seu empreendimento.

 mkdir payment_wallet_project
cd payment_wallet_project 

Para seguir este guia de instruções, irá construir interfaces de programação de aplicações (APIs) destinadas a serem utilizadas em ligação com uma carteira digital utilizada para transacções financeiras.

O código fonte completo pode ser acedido através de um repositório GitHub, que está prontamente disponível para referência e exploração posterior.

Para começar, estabeleça um ambiente virtual utilizando a biblioteca Pipenv como base para o contexto de desenvolvimento do nosso projeto.

 pipenv install django djangorestframework 

A execução desta instrução resultará na instalação das bibliotecas necessárias e no estabelecimento de um ambiente virtual.

Para ativar um ambiente virtual, por favor execute o seguinte comando no seu terminal ou prompt de comando:bashsource /venv/bin/activatePor favor substitua pelo caminho real para o diretório do seu projeto no seu computador. Isto irá ativar o ambiente virtual e permitir-lhe-á utilizar quaisquer pacotes instalados no mesmo para o seu script Python.

 pipenv shell

Para criar um novo projeto Django, navegue até ao seu diretório preferido e execute o comando “django-admin startproject PayApp”. Isto irá iniciar a criação de um novo projeto chamado “PayApp” na localização especificada.

 django-admin startproject PayApp . 

Empregar o sinal de pontuação final (. https://en.wikipedia.org/wiki/. ) após o comando “django-admin” minimiza a probabilidade de uma replicação duplicada da estrutura da pasta primária do projeto dentro do aplicativo Django recém-criado.

Para criar uma nova aplicação Django dentro do diretório do projeto existente, siga estes passos:1. Abra seu terminal e navegue até a pasta raiz do seu projeto Django usando o comando cd .2. Uma vez que você esteja no diretório correto, execute o seguinte comando para criar uma nova aplicação Django chamada “myapp”:bashpython manage.py startapp myapp3.Isso irá gerar um novo diretório chamado “myapp” dentro do diretório “apps” dentro do seu projeto Django. Dentro deste diretório, irá encontrar vários ficheiros que constituem a estrutura básica da sua nova aplicação.

 python manage.py startapp wallet 

Para começar a construir a sua aplicação API, siga as orientações descritas

Creating a Payment Wallet REST API

Para implementar um backend abrangente para a sua aplicação de criptomoeda, é essencial abrir o ficheiro wallet/models.py no seu projeto Django e criar dois modelos separados para a carteira e transacções. Estes modelos servirão de base ao seu esquema de base de dados e fornecerão a estrutura necessária para armazenar e recuperar dados relacionados com contas de utilizadores e transacções dentro do sistema.

 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) 

Para estabelecer um novo ficheiro dentro do diretório da carteira, intitulado “serializers.py”, vamos proceder à geração de um conjunto de serializadores para os modelos da carteira e da transação. Isto facilitará a gestão e organização eficazes dos dados no sistema de backend da nossa aplicação.

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

Os serializadores têm em conta todos os atributos presentes nos esquemas dos modelos da carteira e da transação.

No ficheiro wallet/views.py , definiremos as funções de visualização necessárias para lidar com as funcionalidades de depósito e levantamento da carteira. Estas funções serão responsáveis por processar os pedidos dos utilizadores e atualizar os dados relevantes na base de dados em conformidade. Ao implementar estas vistas, podemos implementar eficazmente a funcionalidade da carteira na nossa aplicação.

 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

Para estabelecer a interface de programação da aplicação Web (API) e especificar como cada ponto final deve ser acedido, vamos criar um novo ficheiro Python chamado “wallet/urls.py” na estrutura do diretório do nosso projeto. Este ficheiro funciona como um componente essencial da arquitetura geral, permitindo uma comunicação perfeita entre os componentes de front-end e os serviços de 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'),

] 

Incorpore os padrões de URL da sua aplicação no ficheirourls.py do seu projeto, incluindo os da aplicação especificada.

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

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

Para incorporar a funcionalidade de uma carteira digital na sua aplicação, é necessário incluir as bibliotecas “wallet” e “rest\_framework” na lista “INSTALLED\_APPS” localizada no ficheiro “PayApp/settings.py”. Isto irá garantir que estas aplicações são corretamente instaladas e integradas no sistema global.

 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

] 

O registo das aplicações wallet e rest\_framework no registo de aplicações do projeto Django é um processo que permite que estes módulos sejam utilizados no contexto mais alargado do projeto, melhorando a sua funcionalidade através do aproveitamento dos recursos fornecidos pela framework Django.

Consumindo a API com modelos Django

Para desenvolver uma interface amigável para interagir com nossa API de backend usando modelos Django, precisaremos estabelecer um novo modelo dentro da pasta “wallet” localizada no diretório “templates”. O modelo específico necessário tem o nome “wallet.html” e deve conter o código HTML subsequente fornecido abaixo.

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

O documento HTML apresenta eficazmente as interfaces de programação de aplicações de depósito e levantamento numa interface gráfica de utilizador esteticamente agradável, utilizando a estrutura Bootstrap visualmente apelativa para fins de design.

Interação do utilizador com formulários

No documento HTML, incorpore um elemento de script e integre-o no manipulador de eventos associado ao evento de submissão do formulário de depósito.

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

Em seguida, incorpore o ouvinte de eventos para o envio do formulário de levantamento, utilizando o código fornecido da seguinte forma:

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

O ouvinte de eventos é responsável pela gestão da submissão dos formulários de depósito e de levantamento, que estão associados aos elementos “#deposit-form” e “#withdraw-form”, respetivamente.

O URL do pedido de pesquisa corresponde aos URLs associados às acções de depósito e de levantamento.

O processo envolve a análise das respostas JSON das transacções de depósito e levantamento para obter o saldo da conta corrente, que é posteriormente obtido através da propriedade data.balance . Posteriormente, estes valores são transformados e apresentados na página Web.

Para apresentar o conteúdo da carteira digital de um utilizador na aplicação Web, é necessário modificar o ficheiro wallet/views.py incorporando uma versão actualizada da função render() que processa o modelo wallet.html . Esta função deve ter em conta quaisquer alterações feitas ao modelo Wallet e garantir que a informação apresentada reflecte com precisão o estado atual da carteira do utilizador.

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

Neste exemplo ilustrativo, vamos utilizar a funcionalidade utilitária do método first() para selecionar a carteira virtual de um único utilizador com o objetivo de demonstrar o seu funcionamento.

Por favor, actualize o ficheiro urls.py no seu projeto, incorporando uma rota URL para a wallet_view , especificando o caminho apropriado, como se mostra abaixo:

 from .views import wallet_view

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

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

Para verificar se todas as alterações foram aplicadas com êxito à base de dados, recomenda-se a execução de uma série de passos. Em primeiro lugar, certifique-se de que as dependências necessárias estão instaladas, executando o comando “makemigrations” no terminal ou na linha de comandos. Isto irá gerar ficheiros de migração com base em quaisquer modificações efectuadas nos modelos do projeto. Em seguida, aplique essas migrações com o comando “migrate”. Quando ambos os processos forem concluídos sem erros, isso indica que as alterações foram implementadas corretamente. Por fim, inicie o aplicativo Django usando o comando “python manage.py runserver” no terminal ou no prompt de comando. O servidor deve agora estar pronto a ser utilizado, permitindo-lhe aceder ao sítio Web ou ao serviço através de um navegador Web.

 python manage.py makemigrations
python manage.py migrate

python manage.py runserver

Para aceder aos destinos do endpoint da nossa interface de programação de aplicações, dirija o seu navegador Web para o URL http://127.0.0.1:8000/api/ .

Resultado esperado:

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

Navegue para o localhost para interagir com a carteira.

Saída esperada:

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

A carteira digital do utilizador apresenta o saldo da sua conta corrente, fornecendo-lhe um meio conveniente de iniciar depósitos e levantamentos, conforme necessário.

Entendendo os modelos do Django e seu papel no consumo de API

Embora os modelos do Django sejam excelentes para exibir dados fixos, eles estão sujeitos a limitações quando se trata de integração com interfaces de programação de aplicativos (APIs).

O sistema de modelos do Django oferece um nível mais restrito de adaptabilidade em comparação com outras alternativas, como Jinja2 ou Twig. Isso se deve à sua dependência de estratégias de renderização predefinidas que necessitam de manipulação manual ao trabalhar com estruturas de dados complexas obtidas de APIs que fornecem informações formatadas em JSON.

Django, uma estrutura web contemporânea amplamente utilizada, não oferece suporte nativo para lidar com pedidos assíncronos no seu sistema de modelos. Apesar dessa limitação, outros frameworks modernos, como o Flask, adotaram o uso da sintaxe async/await em seu processo de desenvolvimento.Como resultado, ao utilizar o mecanismo de template do Django, é necessário completar todas as requisições sequencialmente antes de renderizar uma página web, mesmo que múltiplas fontes de dados sejam necessárias para gerar conteúdo.

Os templates do Django não possuem um mecanismo natural para acomodar erros que podem surgir do uso da API. Não é incomum que exceções sejam lançadas durante tais operações, necessitando de intervenção manual para lidar com elas dentro dos limites do template. Isto pode levar a um código pesado e difícil de manter.

Construa Aplicações Escaláveis

Os templates Django facilitam a separação das camadas de apresentação da lógica de negócio, permitindo que os desenvolvedores se concentrem na composição de código reutilizável e sustentável. No entanto, dadas as suas restrições, os modelos Django podem não ser ideais para lidar com APIs em escalas extensas. Nessas situações, as estruturas de cliente como o React continuam a ser relevantes na construção de sistemas de software escaláveis.