Katkat

Repair a Django Post-Creation Endpoint and Its React Contract

AmazonSoftware Engineer · Online Assessment

Last updated

Implement and repair a Django REST Framework view and serializer for post creation to satisfy frontend React contract requirements, ensure atomic tag associations, and enforce authenticated author assignment.

Problem Statement

You are debugging a social publishing service where the React frontend client creates new blog posts via POST /api/posts/. The frontend expects a specific JSON response format and requires that newly created posts appear under the authenticated user's "My Posts" feed.

Currently, the endpoint is buggy and inconsistent:

  1. User Identity: The post author is taken from the request body rather than the authenticated session user (request.user), allowing impersonation.
  2. Atomicity: Posts and their associated tags are saved non-atomically. If tag validation or creation fails, a dangling post record remains.
  3. Payload Contract: The React client requires:
    • An alias field _id in the response pointing to the post's primary key id.
    • A nested author object containing { "id": int, "username": str }.
    • A list of tag names as strings (tags: ["tech", "django"]), even though tags are stored as separate related models.
    • Default status set to "draft" if omitted.
  4. Visibility: Ensure the post is associated with the requesting user so it queries properly in user-filtered views.

Implement or correct the Django REST Framework view / serializer logic to handle this creation flow properly.

Interface

from rest_framework import serializers
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from django.db import transaction

class PostCreateSerializer(serializers.ModelSerializer):
    # Define necessary fields and validation
    pass

class PostCreateView(APIView):
    # Enforce authentication and atomic creation
    def post(self, request, *args, **kwargs):
        pass

Input & Output Format

  • Request Payload (POST /api/posts/):
{
  "title": "Debugging DRF",
  "content": "Deep dive into serializers.",
  "tags": ["django", "python"],
  "status": "published"
}

Note: status is optional and defaults to "draft".

  • Expected Success Response (201 Created):
{
  "_id": 42,
  "id": 42,
  "title": "Debugging DRF",
  "content": "Deep dive into serializers.",
  "status": "published",
  "author": {
    "id": 7,
    "username": "alice"
  },
  "tags": ["django", "python"],
  "created_at": "2025-01-15T10:30:00Z"
}

Constraints

  • Tag names are unique case-insensitive strings between 1 and 30 alphanumeric characters. If any tag is invalid, the entire transaction must roll back and return 400 Bad Request.
  • Unauthenticated requests must return 401 Unauthorized.
  • Tag associations must reuse existing tags if they already exist in the database, rather than duplicating them.

Hints

Hint 1

Use Django's `transaction.atomic()` context manager to ensure that post record creation and tag relations succeed or fail together.

Hint 2

Pass `request.user` to the serializer save method via `serializer.save(author=request.user)` to avoid client-side spoofing.

Hint 3

Use `serializers.SerializerMethodField` or custom serializer representation overrides (`to_representation`) to map `_id` and serialize the nested author and tag list.

Follow-up questions

  • How would you optimize database queries if the endpoint allowed bulk post creation to prevent N+1 query overhead during tag lookups and associations?
  • How would you handle idempotency so that duplicate submissions from network retries do not create identical posts?
  • If tags could be added concurrently by multiple requests, how would you prevent race conditions when using `get_or_create` on tags?