2
respostas

ERRO DE PK AO ABRIR SWAGGER

Erro ao carregar o Swagger exibido no console: view's ListaMatriculaEstudante raised exception during schema generation; use getattr(self, 'swagger_fake_view', False) to detect and short-circuit this Traceback (most recent call last): File "C:\Users\vitor\Desktop\Workspace\django-alura\curso1\env\Lib\site-packages\drf_yasg\inspectors\base.py", line 42, in call_view_method return view_method() File "C:\Users\vitor\Desktop\Workspace\django-alura\curso1\escola\views.py", line 48, in get_queryset queryset = Matricula.objects.filter(estudante_id=self.kwargs["pk"]).order_by( ~~~~~~~~~~~^^^^^^ KeyError: 'pk' view's ListaMatriculaCurso raised exception during schema generation; use getattr(self, 'swagger_fake_view', False) to detect and short-circuit this Traceback (most recent call last): File "C:\Users\vitor\Desktop\Workspace\django-alura\curso1\env\Lib\site-packages\drf_yasg\inspectors\base.py", line 42, in call_view_method return view_method() File "C:\Users\vitor\Desktop\Workspace\django-alura\curso1\escola\views.py", line 59, in get_queryset queryset = Matricula.objects.filter(curso_id=self.kwargs["pk"]).order_by("id") ~~~~~~~~~~~^^^^^^ KeyError: 'pk'

2 respostas

Erro persiste mesmo após adicionar as doctrings: """ Descrição da View: - Lista Matriculas por id de Curso Parâmetros: - pk (int): O identificador primário do objeto. Deve ser um número inteiro. """

Código completo:

from escola.models import Estudante, Curso, Matricula
from escola.serializers import (
    EstudanteSerializer,
    CursoSerializer,
    MatriculaSerializer,
    ListaMatriculasEstudantesSerializer,
    ListaMatriculasCursoSerializer,
    EstudanteSerializerV2,
)
from rest_framework import viewsets, generics, filters
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework.throttling import UserRateThrottle
from escola.throttles import MatriculaAnonRateThrottle


class EstudanteViewSet(viewsets.ModelViewSet):
    queryset = Estudante.objects.all().order_by("id")
    # serializer_class = EstudanteSerializer
    filter_backends = [
        DjangoFilterBackend,
        filters.OrderingFilter,
        filters.SearchFilter,
    ]
    ordering_fields = ["nome"]
    search_fields = ["nome", "cpf"]

    def get_serializer_class(self):
        if self.request.version == "v2":
            return EstudanteSerializerV2
        return EstudanteSerializer


class CursoViewSet(viewsets.ModelViewSet):
    queryset = Curso.objects.all().order_by("id")
    serializer_class = CursoSerializer


class MatriculaViewSet(viewsets.ModelViewSet):
    queryset = Matricula.objects.all().order_by("id")
    serializer_class = MatriculaSerializer
    throttle_classes = [UserRateThrottle, MatriculaAnonRateThrottle]
    http_method_names = ["get", "post"]


class ListaMatriculaEstudante(generics.ListAPIView):
    """
    Descrição da View:
    - Lista Matriculas por id de Estudante
    Parâmetros:
    - pk (int): O identificador primário do objeto. Deve ser um número inteiro.
    """

    def get_queryset(self):
        queryset = Matricula.objects.filter(estudante_id=self.kwargs["pk"]).order_by(
            "id"
        )
        return queryset

    serializer_class = ListaMatriculasEstudantesSerializer


class ListaMatriculaCurso(generics.ListAPIView):
    """
    Descrição da View:
    - Lista Matriculas por id de Curso
    Parâmetros:
    - pk (int): O identificador primário do objeto. Deve ser um número inteiro.
    """

    def get_queryset(self):
        queryset = Matricula.objects.filter(curso_id=self.kwargs["pk"]).order_by("id")
        return queryset

    serializer_class = ListaMatriculasCursoSerializer

Bom dia!

O erro que você está enfrentando ao abrir o Swagger é causado porque o Swagger tenta gerar a documentação da API automaticamente e, durante esse processo, ele executa métodos como get_queryset() sem ter acesso a parâmetros de rota, como o pk. Por isso, ao acessar self.kwargs["pk"], ocorre o erro KeyError: 'pk'.

Você precisa impedir que o get_queryset() seja executado pelo Swagger durante a geração do schema.

A forma correta de fazer isso é utilizando a verificação if getattr(self, 'swagger_fake_view', False) dentro do método get_queryset(), como o erro já sugere.

Como corrigir

Altera suas views ListaMatriculaEstudante e ListaMatriculaCurso assim:

class ListaMatriculaEstudante(generics.ListAPIView):
    """
    Descrição da View:
    - Lista Matriculas por id de Estudante
    Parâmetros:
    - pk (int): O identificador primário do objeto. Deve ser um número inteiro.
    """

    serializer_class = ListaMatriculasEstudantesSerializer

    def get_queryset(self):
        # Impede erro no Swagger
        if getattr(self, 'swagger_fake_view', False):
            return Matricula.objects.none()
        return Matricula.objects.filter(estudante_id=self.kwargs["pk"]).order_by("id")
class ListaMatriculaCurso(generics.ListAPIView):
    """
    Descrição da View:
    - Lista Matriculas por id de Curso
    Parâmetros:
    - pk (int): O identificador primário do objeto. Deve ser um número inteiro.
    """

    serializer_class = ListaMatriculasCursoSerializer

    def get_queryset(self):
        if getattr(self, 'swagger_fake_view', False):
            return Matricula.objects.none()
        return Matricula.objects.filter(curso_id=self.kwargs["pk"]).order_by("id")
  • O atributo swagger_fake_view é adicionado dinamicamente pelo drf_yasg quando ele está apenas tentando gerar o schema.
  • Quando ele está presente e é True, significa que a view está sendo acessada pelo Swagger, fora de uma requisição real.
  • Retornar Matricula.objects.none() evita o erro e não afeta o comportamento da API em tempo real.