home / skills / aj-geddes / useful-ai-prompts / django-application

django-application skill

/skills/django-application

This skill helps you design and implement production-ready Django apps with models, views, ORM queries, authentication, and admin interfaces.

npx playbooks add skill aj-geddes/useful-ai-prompts --skill django-application

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
11.0 KB
---
name: django-application
description: Develop production-grade Django applications with models, views, ORM queries, authentication, and admin interfaces. Use when building web applications, managing databases with Django ORM, and implementing authentication systems.
---

# Django Application

## Overview

Build comprehensive Django web applications with proper model design, view hierarchies, database operations, user authentication, and admin functionality following Django conventions and best practices.

## When to Use

- Creating Django web applications
- Designing models and database schemas
- Implementing views and URL routing
- Building authentication systems
- Using Django ORM for database operations
- Creating admin interfaces and dashboards

## Instructions

### 1. **Django Project Setup**

```bash
django-admin startproject myproject
cd myproject
python manage.py startapp users
python manage.py startapp products
```

### 2. **Model Design with ORM**

```python
# users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model

class CustomUser(AbstractUser):
    ROLE_CHOICES = [
        ('admin', 'Administrator'),
        ('user', 'Regular User'),
    ]
    profile_picture = models.ImageField(upload_to='profiles/', null=True)
    role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']
        indexes = [
            models.Index(fields=['email']),
            models.Index(fields=['role']),
        ]

    def __str__(self):
        return self.email

# products/models.py
User = get_user_model()

class Product(models.Model):
    STATUS_CHOICES = [
        ('draft', 'Draft'),
        ('published', 'Published'),
    ]

    title = models.CharField(max_length=200, db_index=True)
    slug = models.SlugField(unique=True)
    description = models.TextField()
    price = models.DecimalField(max_digits=10, decimal_places=2)
    stock = models.PositiveIntegerField(default=0)
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='products')
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

    class Meta:
        ordering = ['-created_at']
        unique_together = ['slug', 'owner']

    def __str__(self):
        return self.title

class ProductReview(models.Model):
    product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
    author = models.ForeignKey(User, on_delete=models.CASCADE)
    rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)])
    comment = models.TextField()
    created_at = models.DateTimeField(auto_now_add=True)

    class Meta:
        unique_together = ['product', 'author']
```

### 3. **Views with Class-Based and Function-Based Approaches**

```python
# products/views.py
from django.views import View
from django.views.generic import ListView, DetailView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from django.db.models import Q, Count, Avg
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated

from .models import Product, ProductReview
from .serializers import ProductSerializer

# Class-based view with authentication
class ProductListView(LoginRequiredMixin, ListView):
    model = Product
    template_name = 'products/list.html'
    context_object_name = 'products'
    paginate_by = 20

    def get_queryset(self):
        queryset = Product.objects.filter(status='published')

        # Search and filter
        search = self.request.GET.get('q')
        if search:
            queryset = queryset.filter(
                Q(title__icontains=search) | Q(description__icontains=search)
            )

        # Price range filter
        min_price = self.request.GET.get('min_price')
        max_price = self.request.GET.get('max_price')
        if min_price:
            queryset = queryset.filter(price__gte=min_price)
        if max_price:
            queryset = queryset.filter(price__lte=max_price)

        return queryset.annotate(
            review_count=Count('reviews'),
            avg_rating=Avg('reviews__rating')
        ).order_by('-created_at')

# REST API ViewSet
class ProductViewSet(viewsets.ModelViewSet):
    permission_classes = [IsAuthenticated]
    serializer_class = ProductSerializer
    queryset = Product.objects.all()

    def get_queryset(self):
        return Product.objects.filter(owner=self.request.user)

    @action(detail=True, methods=['post'])
    def add_review(self, request, pk=None):
        product = self.get_object()
        serializer = ProductReviewSerializer(data=request.data)

        if serializer.is_valid():
            serializer.save(product=product, author=request.user)
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    @action(detail=True, methods=['get'])
    def reviews(self, request, pk=None):
        product = self.get_object()
        reviews = product.reviews.all()
        serializer = ProductReviewSerializer(reviews, many=True)
        return Response(serializer.data)
```

### 4. **Authentication and Permissions**

```python
# users/views.py
from django.contrib.auth import authenticate, login, logout
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_protect
from rest_framework.authtoken.models import Token
from rest_framework.permissions import BasePermission

class IsOwner(BasePermission):
    def has_object_permission(self, request, view, obj):
        return obj.owner == request.user

@require_http_methods(['POST'])
@csrf_protect
def login_view(request):
    email = request.POST.get('email')
    password = request.POST.get('password')
    user = authenticate(request, username=email, password=password)

    if user is not None:
        login(request, user)
        token, created = Token.objects.get_or_create(user=user)
        return JsonResponse({
            'success': True,
            'token': token.key,
            'user_id': user.id
        })

    return JsonResponse({'error': 'Invalid credentials'}, status=401)

@require_http_methods(['POST'])
def logout_view(request):
    logout(request)
    return JsonResponse({'success': True})
```

### 5. **Database Queries and Optimization**

```python
# products/queries.py
from django.db.models import Q, Count, Avg, F, Case, When, Value
from django.db.models.functions import Coalesce
from .models import Product, ProductReview

# Optimized queries with select_related and prefetch_related
def get_product_details(product_id):
    return Product.objects.select_related('owner').prefetch_related(
        'reviews__author'
    ).get(id=product_id)

# Aggregation queries
def get_top_products():
    return Product.objects.annotate(
        review_count=Count('reviews'),
        avg_rating=Avg('reviews__rating'),
        total_reviews=Count('reviews', distinct=True)
    ).filter(review_count__gt=0).order_by('-avg_rating')[:10]

# Complex filtering
def search_products(query, category=None, min_price=None, max_price=None):
    queryset = Product.objects.filter(
        Q(title__icontains=query) | Q(description__icontains=query)
    )

    if category:
        queryset = queryset.filter(category=category)
    if min_price:
        queryset = queryset.filter(price__gte=min_price)
    if max_price:
        queryset = queryset.filter(price__lte=max_price)

    return queryset.select_related('owner')

# Bulk operations
def bulk_update_stock(updates):
    products_to_update = []
    for product_id, new_stock in updates.items():
        product = Product.objects.get(id=product_id)
        product.stock = new_stock
        products_to_update.append(product)

    Product.objects.bulk_update(products_to_update, ['stock'])
```

### 6. **URL Routing**

```python
# myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework.authtoken.views import obtain_auth_token
from products.views import ProductViewSet

router = DefaultRouter()
router.register(r'products', ProductViewSet)

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/', include(router.urls)),
    path('api-token-auth/', obtain_auth_token),
]
```

### 7. **Admin Interface Customization**

```python
# products/admin.py
from django.contrib import admin
from .models import Product, ProductReview

@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
    list_display = ['title', 'price', 'stock', 'status', 'owner', 'created_at']
    list_filter = ['status', 'created_at', 'owner']
    search_fields = ['title', 'description']
    readonly_fields = ['created_at', 'updated_at']
    fieldsets = (
        ('Basic Info', {
            'fields': ('title', 'slug', 'owner')
        }),
        ('Details', {
            'fields': ('description', 'price', 'stock', 'status')
        }),
        ('Metadata', {
            'fields': ('created_at', 'updated_at'),
            'classes': ('collapse',)
        }),
    )

    def save_model(self, request, obj, form, change):
        if not change:
            obj.owner = request.user
        super().save_model(request, obj, form, change)

@admin.register(ProductReview)
class ProductReviewAdmin(admin.ModelAdmin):
    list_display = ['product', 'author', 'rating', 'created_at']
    list_filter = ['rating', 'created_at']
    readonly_fields = ['created_at']
```

## Best Practices

### ✅ DO
- Use models for database operations
- Implement proper indexes on frequently queried fields
- Use select_related and prefetch_related for query optimization
- Implement authentication and permissions
- Use Django Forms for form validation
- Cache expensive queries
- Use management commands for batch operations
- Implement logging for debugging
- Use middleware for cross-cutting concerns
- Validate user input

### ❌ DON'T
- Use raw SQL without ORM
- N+1 query problems without optimization
- Store secrets in code
- Trust user input directly
- Override __init__ in models unnecessarily
- Make synchronous heavy operations in views
- Use inheritance models unless necessary
- Expose stack traces in production

## Complete Example

```python
# settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'rest_framework',
    'users',
    'products'
]

AUTH_USER_MODEL = 'users.CustomUser'

REST_FRAMEWORK = {
    'DEFAULT_AUTHENTICATION_CLASSES': [
        'rest_framework.authentication.TokenAuthentication',
    ],
    'DEFAULT_PERMISSION_CLASSES': [
        'rest_framework.permissions.IsAuthenticated',
    ]
}

# models.py + views.py (see sections above)
# urls.py + admin.py (see sections above)
```

Overview

This skill helps you develop production-grade Django applications covering models, views, ORM queries, authentication, and admin interfaces. It provides patterns and examples for project setup, model design, optimized queries, REST APIs, and admin customization. Follow the conventions here to build maintainable, secure, and performant web apps.

How this skill works

The skill guides you through setting up a Django project and apps, defining custom user and product models with indexes and constraints, and implementing class-based and REST views. It demonstrates optimized database access using select_related/prefetch_related, aggregation, bulk updates, and token-based authentication. Admin customization, URL routing, permissions, and common optimizations are included so you can apply them directly to real projects.

When to use it

  • When building a new Django web application or API
  • When designing database schemas and model relationships
  • When implementing authentication, permissions, and token auth
  • When optimizing ORM queries and avoiding N+1 problems
  • When creating admin dashboards and custom admin behaviors

Best practices

  • Define a custom user model early and set AUTH_USER_MODEL
  • Add indexes and unique constraints on frequently queried fields
  • Use select_related and prefetch_related to prevent N+1 queries
  • Guard endpoints with permissions and validate all input
  • Use Django Forms, serializers, and management commands for heavy tasks

Example use cases

  • E-commerce app: Product, review models, paginated product lists, and owner-scoped APIs
  • Content platform: Draft/published workflows, slug uniqueness per owner, and search filters
  • Admin portal: Customized admin list_display, filters, and automatic owner assignment
  • Analytics: Aggregation queries for top-rated items and cached expensive results
  • Bulk operations: Stock updates with bulk_update and background management commands

FAQ

How do I avoid N+1 queries?

Use select_related for single-valued relationships and prefetch_related for reverse or many relationships, and annotate only the fields you need.

When should I create a custom user model?

Create it at project start if you need custom fields or behaviors; changing AUTH_USER_MODEL later is hard.