1
resposta

[Dúvida] DRF: relacionamento automático entre tabelas

Tenho uma dúvida aqui.

Digamos que eu queria criar uma tela que receba os dados do aluno e os dados do curso (seria mais interessante para o exemplo um cadastro de aluno - endereço e uma tabela de relacionamento aluno_endereco, já que ambos seriam inseridos ao mesmo tempo no banco de dados).

Gostaria que ao enviar os dados para persistência, eles fossem automaticamente relacionados, sem a necessidade de uma terceira tela para criar essa relação (aqui entra a parte do exemplo que faz sentido).

Imagino que mesmo com os dados enviados separados, pode haver uma função que obtenha do banco de dados as últimas inserções nas tabelas desejadas, mas é só imaginação. Alguém pode ajudar com esse desafio?

1 resposta

Olá, Carlos! Tudo bem?

Vou te mostrar um exemplo prático de como fazer isso usando serializers aninhados e transações atômicas para garantir que os dados sejam salvos corretamente.

Vamos supor que você tenha os seguintes modelos:

from django.db import models

class Endereco(models.Model):
    rua = models.CharField(max_length=255)
    cidade = models.CharField(max_length=255)
    estado = models.CharField(max_length=255)

class Aluno(models.Model):
    nome = models.CharField(max_length=255)
    email = models.EmailField()
    endereco = models.OneToOneField(Endereco, on_delete=models.CASCADE)

Para criar um endpoint que insira dados de Aluno e Endereco ao mesmo tempo, você pode usar serializers aninhados. Primeiro, crie os serializers:

from rest_framework import serializers
from .models import Aluno, Endereco

class EnderecoSerializer(serializers.ModelSerializer):
    class Meta:
        model = Endereco
        fields = ['rua', 'cidade', 'estado']

class AlunoSerializer(serializers.ModelSerializer):
    endereco = EnderecoSerializer()

    class Meta:
        model = Aluno
        fields = ['nome', 'email', 'endereco']

    def create(self, validated_data):
        endereco_data = validated_data.pop('endereco')
        endereco = Endereco.objects.create(**endereco_data)
        aluno = Aluno.objects.create(endereco=endereco, **validated_data)
        return aluno

Com esses serializers, você pode criar uma view para lidar com a criação de Aluno e Endereco:

from rest_framework import viewsets
from .models import Aluno
from .serializers import AlunoSerializer

class AlunoViewSet(viewsets.ModelViewSet):
    queryset = Aluno.objects.all()
    serializer_class = AlunoSerializer

E, finalmente, registre essa view no seu arquivo de URLs:

from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .views import AlunoViewSet

router = DefaultRouter()
router.register(r'alunos', AlunoViewSet)

urlpatterns = [
    path('', include(router.urls)),
]

Com isso, ao enviar uma requisição POST para o endpoint /alunos/ com os dados do aluno e do endereço, ambos serão salvos no banco de dados e relacionados automaticamente.

Exemplo de requisição JSON:

{
    "nome": "Carlos",
    "email": "carlos@example.com",
    "endereco": {
        "rua": "Rua Exemplo",
        "cidade": "Cidade Exemplo",
        "estado": "Estado Exemplo"
    }
}

Espero ter ajudado e bons estudos!

Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.