12 Prompts for Django: Models, Views, API, and Admin

If you write Django code daily, you know that the framework gives you structure, but the real work is in the details — field choices, query optimization, serializer logic, admin display options. This collection gives you 12 ready-to-use prompts that turn you into a faster, more consistent backend developer. Each prompt is a small contract: paste it, add your context, and get a code snippet you can review, adapt, and commit.

1. Generate a Django Model from a Specification

What it's for: Turn a feature description into a complete models.py with proper field types, relationships, and Meta options.

Prompt:

Act as a senior Django developer. Based on this feature specification, write a Django model. Use django.db.models. Include all necessary fields, ForeignKey with on_delete, many-to-many if needed, choices as TextChoices, Meta ordering, indexes for frequently filtered fields, and __str__. Feature: [describe your feature]

Example: For 'A Product belongs to a Category, has a price, a slug, and a stock level; we need a unique slug per category', the prompt returns:

from django.db import models
from django.utils.text import slugify

class Category(models.Model):
    name = models.CharField(max_length=100)

class Product(models.Model):
    category = models.ForeignKey(Category, on_delete=models.PROTECT, related_name='products')
    name = models.CharField(max_length=200)
    slug = models.SlugField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField(default=0)

    class Meta:
        indexes = [models.Index(fields=['category', 'slug'])]
        ordering = ['-price']

    def __str__(self):
        return self.name

Why it works: The prompt forces the model to think about indexes and relationships, not just fields. The official Django docs on models (docs.djangoproject.com/en/5.0/topics/db/models/) describe every option you can inject this way.

2. Optimize a Query with select_related and prefetch_related

What it's for: Reducing the number of SQL queries in a view or serializer.

Prompt:

You are a Django performance expert. Here is a query with an N+1 problem. Rewrite it using select_related for forward relationships and prefetch_related for reverse and many-to-many. Explain each keyword choice. Query: [paste your query]

Example:

# Before
orders = Order.objects.all()
for order in orders:
    print(order.customer.name)

# After
orders = Order.objects.select_related('customer').all()

For related products on an order, you'd add .prefetch_related('items__product'). The Django docs on querysets (docs.djangoproject.com/en/5.0/ref/models/querysets/) mention these methods specifically for optimizing loops.

3. Build a Class-Based View with Mixins

What it's for: Generating a full CRUD view with a mixin-based structure instead of writing functions from scratch.

Prompt:

Act as a Django instructor. Create a set of class-based views for a model named [Model]. Use LoginRequiredMixin, UserPassesTestMixin for ownership checks, and generic views (ListView, DetailView, CreateView, UpdateView, DeleteView). Provide template names and success_url.

Example: For a Post model owned by a user, the prompt returns a PostCreateView that checks form.instance.author = self.request.user and a PostUpdateView that denies access unless the author matches. This pattern comes from the official generic CBV docs (docs.djangoproject.com/en/5.0/topics/class-based-views/generic-editing/).

4. Write a DRF Serializer with Nested Data

What it's for: Converting a model into a validated API representation with nested objects.

Prompt:

You are a Django REST Framework expert. Write a ModelSerializer for the [Model] class. Include nested serializers for related models, a computed field, and a validate method that checks business rules. Use read_only_fields and extra_kwargs for validation hints.

Example:

from rest_framework import serializers
from .models import Product

class CategorySerializer(serializers.ModelSerializer):
    class Meta:
        model = Category
        fields = ['id', 'name']

class ProductSerializer(serializers.ModelSerializer):
    category = CategorySerializer(read_only=True)
    final_price = serializers.DecimalField(max_digits=10, decimal_places=2, read_only=True)

    class Meta:
        model = Product
        fields = ['id', 'name', 'price', 'final_price', 'category']

    def validate_price(self, value):
        if value <= 0:
            raise serializers.ValidationError('Price must be positive.')
        return value

See the DRF serializer docs (django-rest-framework.org/api-guide/serializers/) for a full list of field options.

5. Generate a DRF ViewSet with Router

What it's for: Building a consistent API endpoint set with minimal code.

Prompt:

Create a Django REST Framework ViewSet for the [Model] model. Provide a ModelSerializer, a filter_backends configuration, and a permission class that allows only authenticated users. Wire the ViewSet to a DRF router and show the URL patterns.

Example: The output typically looks like this:

from rest_framework import viewsets
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from .models import Product, ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.select_related('category')
    serializer_class = ProductSerializer
    permission_classes = [IsAuthenticatedOrReadOnly]

# urls.py
from rest_framework.routers import DefaultRouter
router = DefaultRouter()
router.register('products', ProductViewSet)

The router automatically creates list, detail, create, update, and delete endpoints under /products/. This is documented in the DRF router guide (django-rest-framework.org/api-guide/routers/).

6. Decide Between APIView, GenericView, and ViewSet

What it's for: Receiving architecture guidance when you're not sure which DRF tool fits your case.

Prompt:

Act as a Django REST Framework consultant. Compare APIView, GenericAPIView, and ModelViewSet for this use case: [describe your use case]. Recommend one, explain the tradeoffs in maintainability and code size, and provide a minimal implementation.

Why it matters: Simple endpoints need APIView; endpoints with one or two database models benefit from GenericAPIView; complete CRUD with no custom logic benefits from ViewSet. The DRF api-guide has dedicated pages for each, and citing them in the prompt will make the AI's answer more precise.

7. Customize the Django Admin Site

What it's for: Generating a ModelAdmin class with the right list page, filters, search, and inlines.

Prompt:

You are a Django admin specialist. Write a ModelAdmin for [Model]. Add list_display, list_filter, search_fields, autocomplete_fields, prepopulated_fields if a slug exists, and an inline for the [Related] model. Keep the interface usable for non-technical staff.

Example:

from django.contrib import admin
from .models import Product, StockMovement

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ('name', 'category', 'price', 'stock', 'is_active')
    list_filter = ('category', 'is_active')
    search_fields = ('name', 'slug')
    prepopulated_fields = {'slug': ('name',)}
    autocomplete_fields = ('category',)

@admin.register(StockMovement)
class StockMovementAdmin(admin.ModelAdmin):
    autocomplete_fields = ('product',)

The official admin docs (docs.djangoproject.com/en/5.0/ref/contrib/admin/) explain every attribute here.

8. Write Unit Tests for Models and API Endpoints

What it's for: Getting a test suite that matches Django's TestCase conventions.

Prompt:

Act as a Django developer who follows strict testing practices. Write tests for the [Model] model and for the [API] endpoint. Use factory-free fixtures, setUpTestData for shared data, and assertEqual checks. Cover the happy path and two edge cases: permission denial and invalid input.

Example:

from django.test import TestCase
from rest_framework.test import APIClient

class ProductAPITest(TestCase):
    @classmethod
    def setUpTestData(cls):
        cls.category = Category.objects.create(name='Books')
        cls.product = Product.objects.create(category=cls.category, name='Django Guide', price=29.99)

    def test_list_products_returns_200(self):
        client = APIClient()
        response = client.get('/products/')
        self.assertEqual(response.status_code, 200)

This pattern mirrors the testing documentation in Django (docs.djangoproject.com/en/5.0/topics/testing/) and DRF's testing guide.

9. Create a Custom Management Command

What it's for: Adding a manage.py command for data imports, cleanup, or periodic tasks.

Prompt:

Write a Django custom management command that imports data from a CSV file. Use BaseCommand, add_arguments to accept the file path, handle every row with try/except, and report the number of created and failed records. Include a progress indicator.

Example:

from django.core.management.base import BaseCommand
from csv import DictReader
from myapp.models import Product

class Command(BaseCommand):
    help = 'Import products from a CSV file'

    def add_arguments(self, parser):
        parser.add_argument('csv_file', type=str)

    def handle(self, *args, **options):
        created = 0
        with open(options['csv_file'], newline='') as f:
            for row in DictReader(f):
                try:
                    Product.objects.update_or_create(sku=row['sku'], defaults={'price': row['price']})
                    created += 1
                except Exception as e:
                    self.stderr.write(str(e))
        self.stdout.write(f'Created/updated {created} products')

The structure is defined in the official commands documentation (docs.djangoproject.com/en/5.0/howto/custom-management-commands/).

10. Secure an API with Permissions and Throttling

What it's for: Adding authentication, permission, and throttle rules to an existing DRF view.

Prompt:

You are a DRF security expert. Improve the [View/ViewSet] with IsAuthenticated permission, a custom throttle class, and a rate limit of 100 requests per minute for anonymous users. Show the settings.py config and explain how to test the throttle.

Example of the result:

from rest_framework.throttling import SimpleRateThrottle

class AnonymousRateThrottle(SimpleRateThrottle):
    scope = 'anon'

REST_FRAMEWORK = {
    'DEFAULT_THROTTLE_CLASSES': ['myapp.throttling.AnonymousRateThrottle'],
    'DEFAULT_THROTTLE_RATES': {'anon': '100/min'},
}

DRF's throttling guide (django-rest-framework.org/api-guide/throttling/) shows the exact syntax and default options.

11. Refactor a Fat View into Service Layer

What it's for: Moving business logic out of views and serializers into a maintainable service module.

Prompt:

Act as a Django architect. Extract the business logic from this view into a service class in services.py. Keep the view thin, make the service accept a user and a validated data dict, and return a result or raise a domain exception. Here is the view: [paste].

This approach is promoted by best practice books like 'Two Scoops of Django' (a field guide to maintainable Django) and helps when views grow beyond a few dozen lines.

12. Migrate an Existing Schema Without Downtime

What it's for: Writing safe migrations for large tables or when adding a NOT NULL column.

Prompt:

You are a Django database migration expert. Plan a zero-downtime migration for adding a NOT NULL field with a default to a table with millions of rows. Give a step-by-step migration strategy using Django migration operations and database-specific advice.

The concrete output often includes SeparateDatabaseAndState, AddField with a server-side default, and a data-migration afterward. The official migrations docs (docs.djangoproject.com/en/5.0/topics/migrations/) are the reference here.


This list is not a magic bullet; it's a productivity tool. Take each prompt, replace the placeholders with your actual model or view, and treat the output as a first draft. The best Django code comes from a developer who can recognize good generated code, tweak it, and understand why it works. Copy the prompts, build a cheatsheet for your team, and you'll spend less time on boilerplate and more on the logic that differentiates your product.

← All posts

Comments