AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Drf Api

skill-deadlymind-nanolama-drf-api · by Deadlymind

Builds DRF 3.16 REST endpoints on Django 5.2 — ModelViewSet plus DefaultRouter, a light list serializer split from a detail serializer via get_serializer_class, pagination defaults, a custom export @action, and a drf-spectacular OpenAPI schema. Use when adding or reviewing a ViewSet, serializer, router, or endpoint, splitting list vs detail payloads, wiring pagination, adding a CSV/export action,…

— No reviews yet
0 installs
42 views
0.0% view→install

Install

$ agentstack add skill-deadlymind-nanolama-drf-api

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • ✓ Prompt-injection patterns
  • ✓ Secret / credential exfiltration
  • ✓ Dangerous shell & filesystem operations
  • ✓ Untrusted network calls
  • ✓ Known-malicious package signatures

What it can access

  • ✓ Network access No
  • ✓ Filesystem access No
  • ✓ Shell / process execution No
  • ✓ Environment & secrets No
  • ✓ Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-deadlymind-nanolama-drf-api)

Reliability & compatibility

✓ Security review passed
0 installs to date
— no reviews yet
● 2mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Drf Api? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

DRF API (viewsets, serializers, routers, schema)

When to use

Adding or reviewing a REST endpoint on this stack — a serializer, a ModelViewSet, router wiring, pagination, an export action, or the OpenAPI schema. Tenant scoping and RBAC are prerequisites here, not re-explained: your ViewSet subclasses the fail-closed tenant mixin (multi-tenancy) and declares {resource}_{action} permissions (rbac-permissions) before you add anything below.

Pattern

One ModelViewSet per resource, registered on a single DefaultRouter. Serve a light list serializer (few columns, no nested joins) for list, and a fat detail serializer for retrieve/create/update, chosen in get_serializer_class() by self.action. Pagination is a global default. Side-jobs (export, bulk ops) are custom @actions, not new endpoints. The schema is generated, never hand-written.

Steps / idioms

Split the serializers, pick one by self.action, register a single router, and inherit the tenant + RBAC mixins. One consolidated example:

# serializers.py — thin list row vs. fat detail payload
class InvoiceListSerializer(serializers.ModelSerializer):
    class Meta:
        model = Invoice
        fields = ["id", "number", "total", "status"]           # cheap list row

class InvoiceDetailSerializer(serializers.ModelSerializer):
    lines = InvoiceLineSerializer(many=True, read_only=True)    # nested, costly
    class Meta:
        model = Invoice
        fields = ["id", "number", "total", "status", "lines", "notes"]

# views.py — one ViewSet; serializer chosen by action, tenant + RBAC inherited
class InvoiceViewSet(TenantScopedViewSet):        # scopes queryset fail-closed
    queryset = Invoice.objects.all()
    permission_classes = [InvoiceRBAC]            # {resource}_{action} gate

    def get_serializer_class(self):
        return InvoiceListSerializer if self.action == "list" else InvoiceDetailSerializer

    @action(detail=False, methods=["get"])        # -> /api/invoices/export/
    def export(self, request):
        rows = self.filter_queryset(self.get_queryset())   # stays tenant-scoped
        resp = HttpResponse(content_type="text/csv")
        csv.writer(resp).writerows(rows.values_list("number", "total"))
        return resp

# urls.py — one router derives the URLConf and the browsable/OpenAPI schema
router = DefaultRouter()
router.register(r"invoices", InvoiceViewSet, basename="invoice")
urlpatterns = router.urls

Set a global pagination default so every list is bounded: in settings.py, give REST_FRAMEWORK a DEFAULT_PAGINATION_CLASS of rest_framework.pagination.PageNumberPagination, a PAGE_SIZE (e.g. 25), and a DEFAULT_SCHEMA_CLASS of drf_spectacular.openapi.AutoSchema. Generate the OpenAPI schema with python manage.py spectacular --file schema.yml, and annotate non-obvious actions with @extend_schema so the generated types stay accurate — the frontend consumes this schema (see drf-zod-contract).

Throttle every API so no client can hammer it unbounded: in REST_FRAMEWORK set DEFAULT_THROTTLE_CLASSES (e.g. UserRateThrottle, AnonRateThrottle) and DEFAULT_THROTTLE_RATES (e.g. {"user": "1000/day", "anon": "100/day"}), tuned to your traffic. For a heavy @action, give it its own throttle_scope and a dedicated rate.

Adapt to your repo

Rename Invoice, InvoiceLine, and the entreprise tenant FK to your models. Confirm TenantScopedViewSet and your RBAC permission class exist (they are separate skills). Pick a pagination class that fits your UI — PageNumberPagination for page numbers, CursorPagination for infinite scroll or large offsets. Set PAGE_SIZE to your default.

Gotchas

  • A single fat serializer on list is the classic N+1 — split list vs detail and add

select_related/prefetch_related on the detail queryset (see perf-review).

  • Custom @actions bypass nothing automatically: re-run get_queryset() /

filter_queryset so they stay tenant-scoped, and gate them under RBAC.

  • No global DEFAULT_PAGINATION_CLASS means unbounded list responses — set it once.
  • Stream large exports with StreamingHttpResponse; a full HttpResponse buffers the

whole CSV in memory.

  • get_serializer_class keys off self.action — a typo silently falls through to the

detail serializer; assert the split in a test.

  • Model.save(update_fields=[...]) skips clean() / full validation — enforce business

rules in perform_update or serializer.validate, never by relying on Model.clean firing on save.

  • A serializer source="get_x_display" only resolves when the model field declares

choices=; otherwise it silently breaks — use a SerializerMethodField instead.

  • One ScopedRateThrottle scope is a single shared bucket per user across every endpoint

using it, so a heavy action (bulk export, PDF generation) can starve unrelated endpoints — give it its own throttle_scope so the buckets don't collide.

See also

  • multi-tenancy
  • rbac-permissions
  • drf-zod-contract
  • perf-review

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.