Claude
Skills
Sign in
Back

django-framework

Included with Lifetime
$97 forever

Django full-featured Python web framework with batteries included (ORM, admin, auth)

Backend & APIs

What this skill does

# Django Framework Skill

---
progressive_disclosure:
  entry_point:
    summary: "Full-featured Python web framework with batteries included (ORM, admin, auth)"
    when_to_use:
      - "When building content-heavy web applications"
      - "When needing built-in admin interface"
      - "When using Django ORM and migrations"
      - "When building REST APIs with Django REST Framework"
    quick_start:
      - "pip install django"
      - "django-admin startproject myproject"
      - "python manage.py runserver"
  token_estimate:
    entry: 75-90
    full: 4500-5500
---

## Overview

Django is a high-level Python web framework that encourages rapid development and clean, pragmatic design. Built by experienced developers, it takes care of much of the hassle of web development, enabling focus on writing applications without reinventing the wheel.

**Key Philosophy**: "Batteries included" - Django comes with extensive built-in features including ORM, authentication, admin interface, forms, and security features.

## Core Concepts

### MVT Architecture (Model-View-Template)

Django follows the MVT pattern:
- **Model**: Data layer (ORM models, database schema)
- **View**: Business logic (handles requests, returns responses)
- **Template**: Presentation layer (HTML with Django template language)

### Project vs Apps

- **Project**: The entire Django application (settings, URLs, WSGI config)
- **Apps**: Modular components (blog, auth, API) that can be reused across projects

```bash
# Create project
django-admin startproject myproject
cd myproject

# Create app
python manage.py startapp blog

# Register app in settings.py
INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    # ...
    'blog',
]
```

## Models and ORM

### Model Definition

```python
# models.py
from django.db import models
from django.contrib.auth.models import User

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

    class Meta:
        verbose_name_plural = "categories"
        ordering = ['name']

    def __str__(self):
        return self.name

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

    title = models.CharField(max_length=200)
    slug = models.SlugField(unique=True)
    author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts')
    category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True)
    content = models.TextField()
    status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
    published_at = models.DateTimeField(null=True, blank=True)
    created_at = models.DateTimeField(auto_now_add=True)
    updated_at = models.DateTimeField(auto_now=True)

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

    def __str__(self):
        return self.title
```

### Common Field Types

```python
# Text fields
models.CharField(max_length=200)
models.TextField()
models.SlugField()
models.EmailField()
models.URLField()

# Numeric fields
models.IntegerField()
models.DecimalField(max_digits=10, decimal_places=2)
models.FloatField()

# Date/time fields
models.DateField()
models.DateTimeField()
models.DurationField()

# Boolean
models.BooleanField(default=False)

# Relationships
models.ForeignKey(Model, on_delete=models.CASCADE)
models.ManyToManyField(Model)
models.OneToOneField(Model, on_delete=models.CASCADE)

# Files
models.FileField(upload_to='uploads/')
models.ImageField(upload_to='images/')

# JSON (PostgreSQL)
models.JSONField()
```

### Migrations

```bash
# Create migrations after model changes
python manage.py makemigrations

# View SQL that will be executed
python manage.py sqlmigrate blog 0001

# Apply migrations
python manage.py migrate

# Create empty migration for custom operations
python manage.py makemigrations --empty blog

# Reverse migration
python manage.py migrate blog 0001
```

### QuerySet API

```python
# Basic queries
Post.objects.all()
Post.objects.filter(status='published')
Post.objects.exclude(status='draft')
Post.objects.get(pk=1)  # Returns single object or raises DoesNotExist

# Chaining filters
Post.objects.filter(status='published').filter(category__name='Tech')

# Field lookups
Post.objects.filter(title__icontains='django')  # Case-insensitive contains
Post.objects.filter(published_at__year=2024)
Post.objects.filter(published_at__gte=datetime(2024, 1, 1))
Post.objects.filter(author__username__startswith='john')

# Ordering
Post.objects.order_by('-published_at')
Post.objects.order_by('category', '-created_at')

# Limiting
Post.objects.all()[:5]  # First 5
Post.objects.all()[5:10]  # Offset pagination

# Aggregation
from django.db.models import Count, Avg, Sum
Category.objects.annotate(post_count=Count('post'))
Post.objects.aggregate(avg_length=Avg('content__length'))

# Q objects for complex queries
from django.db.models import Q
Post.objects.filter(Q(status='published') | Q(author=request.user))
Post.objects.filter(Q(status='published') & ~Q(category=None))

# F expressions for field comparisons
from django.db.models import F
Post.objects.filter(updated_at__gt=F('published_at'))

# Select/Prefetch related (performance optimization)
Post.objects.select_related('author', 'category')  # SQL JOIN
Post.objects.prefetch_related('tags')  # Separate query for M2M
```

### Model Methods and Properties

```python
class Post(models.Model):
    # ... fields ...

    @property
    def is_published(self):
        return self.status == 'published' and self.published_at is not None

    def get_absolute_url(self):
        from django.urls import reverse
        return reverse('post_detail', kwargs={'slug': self.slug})

    def save(self, *args, **kwargs):
        # Auto-generate slug if not provided
        if not self.slug:
            from django.utils.text import slugify
            self.slug = slugify(self.title)
        super().save(*args, **kwargs)

    class Meta:
        verbose_name = "blog post"
        verbose_name_plural = "blog posts"
```

## Views

### Function-Based Views (FBV)

```python
# views.py
from django.shortcuts import render, get_object_or_404, redirect
from django.http import JsonResponse, HttpResponse
from django.contrib.auth.decorators import login_required
from .models import Post
from .forms import PostForm

def post_list(request):
    posts = Post.objects.filter(status='published').select_related('author', 'category')
    context = {'posts': posts}
    return render(request, 'blog/post_list.html', context)

def post_detail(request, slug):
    post = get_object_or_404(Post, slug=slug, status='published')
    return render(request, 'blog/post_detail.html', {'post': post})

@login_required
def post_create(request):
    if request.method == 'POST':
        form = PostForm(request.POST)
        if form.is_valid():
            post = form.save(commit=False)
            post.author = request.user
            post.save()
            return redirect('post_detail', slug=post.slug)
    else:
        form = PostForm()
    return render(request, 'blog/post_form.html', {'form': form})

def api_posts(request):
    posts = Post.objects.filter(status='published').values('title', 'slug', 'published_at')
    return JsonResponse(list(posts), safe=False)
```

### Class-Based Views (CBV)

```python
# views.py
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.urls import reverse_lazy
from .models import Post

class PostListView(ListView):
    model = Post
    template_name = 'blog/post_list.html'
    context_object_name = 'posts'
    paginate_by = 10

    def get_queryset(self):
        return Post.objects.filter(

Related in Backend & APIs