Add Slug Field
Create SEO-friendly URLs in Django
🔗 What is a Slug Field?
A slug is a URL-friendly version of text, containing only letters, numbers, hyphens, and underscores. Slugs make URLs readable and SEO-friendly, like "my-first-post" instead of "123".
from django.db import models
class Article(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(unique=True)
Slug Benefits
SEO Friendly
Better search engine rankings
User Friendly
Easy to read and remember
Unique IDs
Identify resources uniquely
Performance
Indexed database lookups
🔹 Add Slug to Model
Add a SlugField to your Django model to store URL-friendly versions of titles. The unique=True parameter ensures no two objects have the same slug.
# models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
def __str__(self):
return self.title
URL Example:
Before: /post/123/
After: /post/my-awesome-article/
🔹 Auto-Generate Slug
Automatically create slugs from titles using Django's slugify function. Override the save method to generate slugs when creating new objects without manual input.
# models.py
from django.db import models
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True, blank=True)
content = models.TextField()
def save(self, *args, **kwargs):
if not self.slug:
self.slug = slugify(self.title)
super().save(*args, **kwargs)
def __str__(self):
return self.title
Example:
Title: "My First Blog Post!"
Slug: "my-first-blog-post"
🔹 Handle Duplicate Slugs
Prevent duplicate slug errors by adding numbers to make each slug unique. This ensures that posts with similar titles get different slugs automatically.
# models.py
from django.db import models
from django.utils.text import slugify
class Post(models.Model):
title = models.CharField(max_length=200)
slug = models.SlugField(max_length=200, unique=True, blank=True)
content = models.TextField()
def save(self, *args, **kwargs):
if not self.slug:
base_slug = slugify(self.title)
slug = base_slug
counter = 1
while Post.objects.filter(slug=slug).exists():
slug = f"{base_slug}-{counter}"
counter += 1
self.slug = slug
super().save(*args, **kwargs)
Example:
Post 1: "hello-world"
Post 2: "hello-world-1"
Post 3: "hello-world-2"
🔹 Use Slug in URLs
Configure your URL patterns to use slugs instead of numeric IDs. This creates clean, readable URLs that are better for SEO and user experience.
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('post/<slug:slug>/', views.post_detail, name='post_detail'),
]
# views.py
from django.shortcuts import render, get_object_or_404
from .models import Post
def post_detail(request, slug):
post = get_object_or_404(Post, slug=slug)
return render(request, 'post_detail.html', {'post': post})
🔹 Display Slug in Admin
Configure Django admin to automatically populate the slug field based on the title. The prepopulated_fields option creates the slug as you type the title.
# admin.py
from django.contrib import admin
from .models import Post
@admin.register(Post)
class PostAdmin(admin.ModelAdmin):
list_display = ['title', 'slug', 'created_at']
prepopulated_fields = {'slug': ('title',)}
search_fields = ['title', 'content']
Admin Features:
- Auto-fill slug as you type title
- Edit slug manually if needed
- See slug in list view
- Search by slug
🔹 Run Migrations
After adding the slug field to your model, create and apply migrations to update your database schema with the new field.
# Create migration
python manage.py makemigrations
# Apply migration
python manage.py migrate
Output:
✓ Migrations for 'blog':
0002_post_slug.py
✓ Running migrations: OK