python 27 lines · 1 tab

Django database migrations best practices

Priya Sharma Jan 2026
1 tab
from django.db import migrations


def populate_slugs(apps, schema_editor):
    """Generate slugs for existing posts."""
    Post = apps.get_model('blog', 'Post')
    from django.utils.text import slugify

    for post in Post.objects.filter(slug__isnull=True):
        post.slug = slugify(post.title)
        post.save()


def reverse_populate_slugs(apps, schema_editor):
    """Clear slugs."""
    Post = apps.get_model('blog', 'Post')
    Post.objects.update(slug=None)


class Migration(migrations.Migration):
    dependencies = [
        ('blog', '0002_post_slug'),
    ]

    operations = [
        migrations.RunPython(populate_slugs, reverse_populate_slugs),
    ]
1 file · python Explain with highlit

Migrations track database schema changes. I use makemigrations after model changes and review generated migrations. For data migrations, I create empty migrations with makemigrations --empty and write RunPython operations. I test migrations on dev data before production. For reversibility, I implement reverse() functions. I squash old migrations periodically to reduce count. In team environments, I coordinate migrations to avoid conflicts. For zero-downtime deployments, I split destructive changes across releases. This keeps database schema in sync with code safely.


Related snips

python
import os
import stat

for root, _dirs, files in os.walk('/etc'):
    for name in files:
        path = os.path.join(root, name)

Python security audit script for exposed risky filesystem state

python auditing host-security
by Kai Nakamura 1 tab
python
class Product(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    cost = models.DecimalField(max_digits=10, decimal_places=2)
    margin = models.DecimalField(max_digits=5, decimal_places=2, blank=True)

Django model signals vs overriding save

django python models
by Priya Sharma 2 tabs
python
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [

Django URL namespacing and reverse lookups

django python urls
by Priya Sharma 3 tabs
ruby
# Vulnerable: user input is concatenated directly into SQL.
email = params[:email]
password = params[:password]

sql = "SELECT * FROM users WHERE email = '#{email}' AND password_hash = '#{password}'"
user = ActiveRecord::Base.connection.execute(sql).first

SQL injection prevention with unsafe and safe query patterns

sql-injection owasp database
by Kai Nakamura 3 tabs
python
import graphene
from graphene_django import DjangoObjectType
from blog.models import Post, Comment


class PostType(DjangoObjectType):

Django GraphQL with Graphene

django python graphql
by Priya Sharma 2 tabs
ruby
class AddSettingsToAccounts < ActiveRecord::Migration[7.1]
  disable_ddl_transaction!

  def change
    add_column :accounts, :settings, :jsonb, null: false, default: {}

Postgres JSONB Partial Index for Feature Flags

rails postgres jsonb
by codesnips 3 tabs

Share this code

Here's the card — post it anywhere.

Django database migrations best practices — share card
Link copied