Task tracker API: owner-scoped ViewSet with an object-level permission

Python · Django · advanced · modification

Adds the task-tracker API: `Task` model (with the initial migration), serializer, an `IsTaskOwner` object-level permission, and a `TaskViewSet` wired through a router. The queryset is scoped to `request.user` and the permission class is applied to every action, so ownership is enforced twice. `owner` and the timestamps are read-only over the wire; creates assign the owner server-side. Statuses and due dates are intentionally unconstrained — the tracker has no workflow rules.

A small team's internal project tracker. The API is internet-exposed and every user must only ever see and touch their own tasks; a leak across users is the one thing this endpoint cannot do. The `tracker` app (package and `apps.py` from `startapp`) and `rest_framework` are already in `INSTALLED_APPS`.

Requirements

Files touched

--- tracker/models.py
+from django.conf import settings
+from django.db import models
+
+
+class Task(models.Model):
+    class Status(models.TextChoices):
+        TODO = "todo", "To do"
+        IN_PROGRESS = "in_progress", "In progress"
+        DONE = "done", "Done"
+
+    title = models.CharField(max_length=200)
+    description = models.TextField(blank=True, default="")
+    status = models.CharField(
+        max_length=20,
+        choices=Status.choices,
+        default=Status.TODO,
+    )
+    due_date = models.DateField(null=True, blank=True)
+    owner = models.ForeignKey(
+        settings.AUTH_USER_MODEL,
+        on_delete=models.CASCADE,
+        related_name="tasks",
+    )
+    created_at = models.DateTimeField(auto_now_add=True)
+    updated_at = models.DateTimeField(auto_now=True)
+
+    class Meta:
+        ordering = ["-created_at"]
+

Review this PR

Python practice