Complete worked example
python
from drf_lab import setup
setup()
from django.urls import path
from drf_spectacular.generators import SchemaGenerator
from drf_spectacular.validation import validate_schema
from rest_framework import generics, serializers
from rest_framework.response import Response
from rest_framework.test import APIRequestFactory
from drf_lab import reset_fixture
from drf_lab.models import Role
class PublicRole(serializers.ModelSerializer):
class Meta:
model = Role
fields = ["id", "title", "country"]
class RoleList(generics.ListAPIView):
serializer_class = PublicRole
def get_queryset(self):
return Role.objects.filter(owner__username="alice", country=self.request.query_params.get("country", "UA")).order_by("id")
urlpatterns = [path("roles/", RoleList.as_view())]
def inspect_example(country):
reset_fixture()
document = SchemaGenerator(patterns=urlpatterns).get_schema(request=None, public=True)
validate_schema(document)
properties = document["components"]["schemas"]["PublicRole"]["properties"]
response = RoleList.as_view()(APIRequestFactory().get("/roles/", {"country": country}))
return {"properties": sorted(properties), "get_documented": "get" in document["paths"]["/roles/"],
"status": response.status_code, "rows": list(response.data)}- Reasoning
- The public serializer declares id, title and country. SchemaGenerator inspects that contract for the /roles/ GET operation. The same generic view serializes a real owned country selection, allowing the test to compare both the component properties and returned rows. Schema validation checks the document format, while the response assertions check application behavior. Neither test substitutes for the other. The owned view has a deliberately simple fixture principal; a real public schema must not enumerate private user data while generating documentation.