20 Prompts for Django: From Models to REST API

Introduction

Django is one of the most popular Python web frameworks, powering everything from small blogs to large-scale platforms like Instagram and Pinterest. As a backend developer, you know that building Django applications involves repetitive tasks: writing models, creating views, setting up serializers, configuring the admin panel, and debugging performance issues. With the rise of AI coding assistants (like ChatGPT, Claude, and GitHub Copilot), you can dramatically accelerate your workflow — but only if you use the right prompts.

This article provides a curated collection of 20 ready-to-use prompts for Django development. Each prompt is designed to be copy-pasted into your AI assistant, with explanations of the task it solves and a concrete example. Whether you are a junior developer learning Django or a senior architect optimizing a production app, these prompts will save you hours every week.

Why Use Prompts for Django?

AI assistants excel at generating boilerplate code, debugging errors, and suggesting best practices — but they need precise instructions. A vague prompt like "write a Django view" will produce generic code that may not fit your project's structure. A specific prompt, on the other hand, includes details about your models, URL patterns, serialization needs, and authentication requirements. The results are production-ready snippets that require minimal editing.

According to a 2025 Stack Overflow survey, 44% of developers use AI tools daily, and the most common use case is generating code snippets (source: Stack Overflow Developer Survey 2025). Django developers, in particular, benefit from prompts because the framework has strong conventions (e.g., Model-View-Template pattern, class-based views) that are easy for AI to replicate.


1. Prompts for Django Models

Prompt 1: Create a Basic Model with Fields

When to use: You need a new model for a blog, e-commerce product, or any data entity.
Prompt:

Create a Django model called 'Product' with the following fields:
- name (CharField, max_length=200)
- description (TextField, blank=True)
- price (DecimalField, max_digits=10, decimal_places=2)
- created_at (DateTimeField, auto_now_add=True)
- updated_at (DateTimeField, auto_now=True)
Add a __str__ method that returns the product name.
Also add a Meta class with verbose_name and verbose_name_plural set to 'Product' and 'Products'.

Example output:

from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name = 'Product'
        verbose_name_plural = 'Products'

Prompt 2: Add ForeignKey and Related Fields

When to use: You need to link models (e.g., Order → Product).
Prompt:

Extend the 'Product' model by adding a 'Category' model with:
- name (CharField, max_length=100, unique=True)
- slug (SlugField, unique=True)
Then add a ForeignKey field 'category' to the Product model, with on_delete=models.CASCADE and related_name='products'.
Also add a 'stock' IntegerField with default=0 to Product.

Example output:

class Category(models.Model):
    name = models.CharField(max_length=100, unique=True)
    slug = models.SlugField(unique=True)

    def __str__(self):
        return self.name

class Product(models.Model):
    category = models.ForeignKey(Category, on_delete=models.CASCADE, related_name='products')
    name = models.CharField(max_length=200)
    description = models.TextField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.IntegerField(default=0)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    def __str__(self):
        return self.name

Prompt 3: Add Custom Model Manager

When to use: You need a custom queryset (e.g., active products, products in stock).
Prompt:

Create a custom model manager called 'ProductManager' for the Product model that adds a method 'in_stock()' which returns products with stock > 0.
Also add a method 'active()' that returns products whose 'is_active' field is True.
Assume the Product model has a BooleanField 'is_active' with default=True.

Example output:

class ProductManager(models.Manager):
    def in_stock(self):
        return self.filter(stock__gt=0)

    def active(self):
        return self.filter(is_active=True)

class Product(models.Model):
    # ... other fields
    is_active = models.BooleanField(default=True)
    objects = ProductManager()

2. Prompts for Django Views

Prompt 4: Create a ListView with Pagination

When to use: You need a page that displays a list of objects.
Prompt:

Create a class-based ListView for the Product model. Name it 'ProductListView'.
- Use template 'shop/product_list.html'
- Paginate by 12 items per page
- Order products by '-created_at'
- Add context variable 'category' that gets the current category from URL (e.g., /products/<slug:category_slug>/)

Example output:

from django.views.generic import ListView
from .models import Product, Category

class ProductListView(ListView):
    model = Product
    template_name = 'shop/product_list.html'
    paginate_by = 12
    ordering = ['-created_at']

    def get_queryset(self):
        queryset = super().get_queryset()
        category_slug = self.kwargs.get('category_slug')
        if category_slug:
            queryset = queryset.filter(category__slug=category_slug)
        return queryset

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        category_slug = self.kwargs.get('category_slug')
        if category_slug:
            context['category'] = Category.objects.get(slug=category_slug)
        return context

Prompt 5: Create a DetailView with Related Objects

When to use: You need a product detail page that also shows related items.
Prompt:

Create a DetailView for the Product model called 'ProductDetailView'.
- Template: 'shop/product_detail.html'
- In get_context_data, add a 'related_products' queryset that returns 4 random products from the same category, excluding the current product.
- Use select_related and prefetch_related to optimize queries: select_related('category'), prefetch_related('reviews').

Example output:

from django.views.generic import DetailView
from .models import Product

class ProductDetailView(DetailView):
    model = Product
    template_name = 'shop/product_detail.html'

    def get_queryset(self):
        return Product.objects.select_related('category').prefetch_related('reviews')

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        product = self.get_object()
        context['related_products'] = Product.objects.filter(
            category=product.category
        ).exclude(pk=product.pk).order_by('?')[:4]
        return context

Prompt 6: Create a FormView for User Registration

When to use: You need a registration form with email, username, and password.
Prompt:

Create a FormView for user registration called 'RegisterView'.
- Use Django's built-in UserCreationForm but add an email field.
- On successful form submission, log the user in automatically and redirect to the home page.
- Use the 'registration/register.html' template.

Example output:

from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login
from django.views.generic.edit import FormView
from django.urls import reverse_lazy

class CustomUserCreationForm(UserCreationForm):
    email = forms.EmailField(required=True)

    class Meta:
        model = User
        fields = ('username', 'email', 'password1', 'password2')

class RegisterView(FormView):
    template_name = 'registration/register.html'
    form_class = CustomUserCreationForm
    success_url = reverse_lazy('home')

    def form_valid(self, form):
        user = form.save()
        login(self.request, user)
        return super().form_valid(form)

3. Prompts for Django REST API (DRF)

Prompt 7: Create a ModelSerializer

When to use: You need to serialize a model for an API endpoint.
Prompt:

Create a ModelSerializer for the Product model. Include all fields, but make 'created_at' and 'updated_at' read-only.
Add a custom field 'category_name' that returns the category's name.

Example output:

from rest_framework import serializers
from .models import Product

class ProductSerializer(serializers.ModelSerializer):
    category_name = serializers.CharField(source='category.name', read_only=True)

    class Meta:
        model = Product
        fields = '__all__'
        read_only_fields = ('created_at', 'updated_at')

Prompt 8: Create a ViewSet with Filtering

When to use: You need a full CRUD API endpoint with search and ordering.
Prompt:

Create a ModelViewSet for the Product model called 'ProductViewSet'.
- Use the ProductSerializer from above.
- Add filtering by category (exact match) and price (range via query params min_price and max_price).
- Enable search on 'name' and 'description'.
- Enable ordering by 'price' and 'created_at'.
- Use DjangoFilterBackend, SearchFilter, and OrderingFilter.

Example output:

from rest_framework import viewsets, filters
from django_filters.rest_framework import DjangoFilterBackend
from .models import Product
from .serializers import ProductSerializer

class ProductViewSet(viewsets.ModelViewSet):
    queryset = Product.objects.select_related('category').all()
    serializer_class = ProductSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = {
        'category': ['exact'],
        'price': ['gte', 'lte'],
    }
    search_fields = ['name', 'description']
    ordering_fields = ['price', 'created_at']

Prompt 9: Create a Custom API Endpoint (Top Products)

When to use: You need a non-CRUD endpoint, e.g., top-selling products.
Prompt:

Create a custom APIView or ViewSet action that returns the top 10 most sold products.
Assume the Product model has a 'sales_count' IntegerField.
Use a ViewSet action called 'top_selling' with GET method.

Example output:

from rest_framework.decorators import action
from rest_framework.response import Response

class ProductViewSet(viewsets.ModelViewSet):
    # ... existing code

    @action(detail=False, methods=['get'])
    def top_selling(self, request):
        top_products = self.get_queryset().order_by('-sales_count')[:10]
        serializer = self.get_serializer(top_products, many=True)
        return Response(serializer.data)

Prompt 10: Add Authentication and Permissions

When to use: You need to restrict API access.
Prompt:

Configure the ProductViewSet to:
- Require authentication for all endpoints except 'list' and 'retrieve'.
- Allow only admin users to create, update, or delete products.
- Use TokenAuthentication for authenticated requests.

Example output:

from rest_framework.permissions import IsAuthenticatedOrReadOnly, IsAdminUser
from rest_framework.authentication import TokenAuthentication

class ProductViewSet(viewsets.ModelViewSet):
    authentication_classes = [TokenAuthentication]
    permission_classes = [IsAuthenticatedOrReadOnly]

    def get_permissions(self):
        if self.action in ('create', 'update', 'partial_update', 'destroy'):
            self.permission_classes = [IsAdminUser]
        return super().get_permissions()

4. Prompts for Django Admin

Prompt 11: Register a Model with Custom Display

When to use: You want a clean admin interface for a model.
Prompt:

Register the Product model in Django admin with:
- list_display: ['name', 'category', 'price', 'stock', 'is_active', 'created_at']
- list_filter: ['category', 'is_active']
- search_fields: ['name', 'description']
- ordering: ['-created_at']
- list_editable: ['price', 'stock', 'is_active']
- prepopulated_fields: {'slug': ('name',)} (assume slug field exists)

Example output:

from django.contrib import admin
from .models import Product

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ['name', 'category', 'price', 'stock', 'is_active', 'created_at']
    list_filter = ['category', 'is_active']
    search_fields = ['name', 'description']
    ordering = ['-created_at']
    list_editable = ['price', 'stock', 'is_active']
    prepopulated_fields = {'slug': ('name',)}

Prompt 12: Add Inline Models

When to use: You want to edit related objects on the same admin page (e.g., order items inside an order).
Prompt:

Create a TabularInline for the 'OrderItem' model and add it to the 'Order' admin.
OrderItem fields: product (ForeignKey), quantity (IntegerField), price (DecimalField).
Make the inline read-only for 'price'.

Example output:

class OrderItemInline(admin.TabularInline):
    model = OrderItem
    extra = 1
    readonly_fields = ['price']

@admin.register(Order)
class OrderAdmin(admin.ModelAdmin):
    inlines = [OrderItemInline]

Prompt 13: Custom Admin Action

When to use: You need a bulk action, e.g., mark products as inactive.
Prompt:

Add a custom admin action called 'mark_as_inactive' that sets is_active=False for selected products.
Add a short description: 'Mark selected products as inactive'.

Example output:

def mark_as_inactive(modeladmin, request, queryset):
    queryset.update(is_active=False)
mark_as_inactive.short_description = 'Mark selected products as inactive'

class ProductAdmin(admin.ModelAdmin):
    actions = [mark_as_inactive]

5. Prompts for Performance Optimization

Prompt 14: Add Database Indexes

When to use: Queries on a field are slow.
Prompt:

Add a database index to the 'created_at' field of the Product model. Also add a unique constraint on the combination of 'name' and 'category'.

Example output:

class Product(models.Model):
    # ... fields
    created_at = models.DateTimeField(auto_now_add=True, db_index=True)

    class Meta:
        unique_together = ['name', 'category']

Prompt 15: Optimize Query with select_related and prefetch_related

When to use: You have an N+1 query problem.
Prompt:

Rewrite the following view to use select_related and prefetch_related to avoid N+1 queries:
[Paste inefficient view code].
Assume Product has ForeignKey to Category and ManyToMany to Tag.

Example output:

def product_list(request):
    products = Product.objects.select_related('category').prefetch_related('tags').all()
    return render(request, 'shop/product_list.html', {'products': products})

Prompt 16: Add Caching with Redis/Memcached

When to use: A view is hit frequently and data doesn't change often.
Prompt:

Add caching to the ProductListView using Django's cache framework. Cache the queryset for 15 minutes.
Use the 'default' cache backend (assume Redis is configured).

Example output:

from django.views.decorators.cache import cache_page
from django.utils.decorators import method_decorator

@method_decorator(cache_page(60 * 15), name='dispatch')
class ProductListView(ListView):
    # ... existing code

6. Prompts for Testing and Debugging

Prompt 17: Write Unit Tests for a Model

When to use: You need tests for model methods or constraints.
Prompt:

Write unit tests for the Product model:
- Test that a product's __str__ returns its name.
- Test that a product with stock=0 is not in the 'in_stock' queryset.
- Test that creating a product without a name raises an error.
Use Django's TestCase and factory_boy if available.

Example output:

from django.test import TestCase
from .models import Product, Category

class ProductModelTest(TestCase):
    def setUp(self):
        self.category = Category.objects.create(name='Books')

    def test_str_returns_name(self):
        product = Product.objects.create(name='Django for Beginners', category=self.category, price=29.99)
        self.assertEqual(str(product), 'Django for Beginners')

    def test_in_stock_queryset(self):
        product = Product.objects.create(name='Test', category=self.category, price=10, stock=0)
        self.assertNotIn(product, Product.objects.in_stock())

Prompt 18: Debug a Slow Query

When to use: You suspect a query is slow and want to analyze it.
Prompt:

Given the following queryset:
products = Product.objects.filter(category__name='Electronics').order_by('-price').select_related('category')
Explain how to use Django Debug Toolbar to identify N+1 queries, and write the equivalent raw SQL query.

Example output:
To use Django Debug Toolbar, add it to INSTALLED_APPS and MIDDLEWARE. It will show SQL queries on each page. For the given queryset, the raw SQL is:

SELECT * FROM shop_product
INNER JOIN shop_category ON shop_product.category_id = shop_category.id
WHERE shop_category.name = 'Electronics'
ORDER BY shop_product.price DESC;

Prompt 19: Write a Migration for Data Transformation

When to use: You need to backfill data or rename fields.
Prompt:

Write a Django data migration that converts all product prices from USD to EUR (assume 1 USD = 0.92 EUR).
The migration should be reversible.

Example output:

from django.db import migrations

def convert_prices(apps, schema_editor):
    Product = apps.get_model('shop', 'Product')
    for product in Product.objects.all():
        product.price = product.price * 0.92
        product.save()

def reverse_convert(apps, schema_editor):
    Product = apps.get_model('shop', 'Product')
    for product in Product.objects.all():
        product.price = product.price / 0.92
        product.save()

class Migration(migrations.Migration):
    dependencies = [
        ('shop', '0001_initial'),
    ]
    operations = [
        migrations.RunPython(convert_prices, reverse_convert),
    ]

Prompt 20: Generate API Documentation with drf-spectacular

When to use: You need OpenAPI/Swagger docs for your API.
Prompt:

Set up drf-spectacular for the ProductViewSet. Include:
- Install the package
- Add to INSTALLED_APPS
- Configure URL patterns for schema and Swagger UI
- Add a description tag 'products' to the ViewSet

Example output:

# settings.py
INSTALLED_APPS += ['drf_spectacular']
REST_FRAMEWORK['DEFAULT_SCHEMA_CLASS'] = 'drf_spectacular.openapi.AutoSchema'

# urls.py
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
urlpatterns += [
    path('api/schema/', SpectacularAPIView.as_view(), name='schema'),
    path('api/docs/', SpectacularSwaggerView.as_view(url_name='schema'), name='swagger-ui'),
]

# views.py
from drf_spectacular.utils import extend_schema

@extend_schema(tags=['products'])
class ProductViewSet(viewsets.ModelViewSet):
    ...

Conclusion

These 20 prompts cover the most common Django development tasks — from defining models and views to building REST APIs, configuring the admin panel, and optimizing performance. By using precise, context-rich prompts with your AI assistant, you can generate production-ready code in seconds instead of minutes.

Remember that AI-generated code should always be reviewed and tested. Use Django's built-in test runner, debug toolbar, and migration system to validate the output. As the Django ecosystem evolves (e.g., Django 5.x with async views, improved ORM), keep your prompts up-to-date by specifying the Django version in your requests.

Start experimenting with these prompts today — and watch your Django development speed double.

← All posts

Comments