Useful Django snippets, patterns, and quick references.
# myapp/management/commands/my_command.py from django.core.management.base import BaseCommand class Command(BaseCommand): help = "Description of your command" def add_arguments(self, parser): parser.add_argument("name", type=str) parser.add_argument("--dry-run", action="store_true") def handle(self, *args, **options): name = options["name"] if options["dry_run"]: self.stdout.write(f"Would process: {name}") return self.stdout.write(self.style.SUCCESS(f"Done: {name}"))
MyModel.objects.bulk_create( [MyModel(field="value") for _ in range(100)], ignore_conflicts=True, )
from django.db.models import OuterRef, Subquery latest_comment = Comment.objects.filter( post=OuterRef("pk") ).order_by("-created_at") Post.objects.annotate( latest_comment_text=Subquery(latest_comment.values("text")[:1]) )
from django.db.models import F Product.objects.filter(pk=1).update(stock=F("stock") - 1)
from django.db import models class TimeStampedModel(models.Model): created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) class Meta: abstract = True
class PublishedManager(models.Manager): def get_queryset(self): return super().get_queryset().filter(status="published") class Article(TimeStampedModel): title = models.CharField(max_length=200) status = models.CharField(max_length=20, default="draft") objects = models.Manager() # default published = PublishedManager() # Usage: Article.published.all()
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status class ItemView(APIView): def get(self, request, pk): try: item = Item.objects.get(pk=pk) except Item.DoesNotExist: return Response( {"error": "Item not found"}, status=status.HTTP_404_NOT_FOUND, ) serializer = ItemSerializer(item) return Response(serializer.data)
from django.test import TestCase, Client from django.urls import reverse class ArticleViewTest(TestCase): def setUp(self): self.client = Client() self.article = Article.objects.create( title="Test", status="published" ) def test_article_detail(self): url = reverse("article-detail", args=[self.article.pk]) response = self.client.get(url) self.assertEqual(response.status_code, 200) self.assertContains(response, "Test")
from django.test import TestCase, override_settings class MyTest(TestCase): @override_settings(DEBUG=True, CACHES={"default": {"BACKEND": "django.core.cache.backends.dummy.DummyCache"}}) def test_with_custom_settings(self): pass
# Shell plus (needs django-extensions) python manage.py shell_plus --print-sql # Show all URLs python manage.py show_urls # Reset migrations for an app python manage.py migrate myapp zero # Create superuser non-interactively DJANGO_SUPERUSER_PASSWORD=pass python manage.py createsuperuser --noinput --username admin --email admin@example.com # Dump data as fixture python manage.py dumpdata myapp.MyModel --indent 2 > fixture.json
python manage.py squashmigrations myapp 0001 0015
python manage.py makemigrations myapp --empty -n my_data_migration
from django.db import migrations def forwards(apps, schema_editor): MyModel = apps.get_model("myapp", "MyModel") for obj in MyModel.objects.filter(status="old"): obj.status = "new" obj.save(update_fields=["status"]) def backwards(apps, schema_editor): pass # or reverse the migration class Migration(migrations.Migration): dependencies = [ ("myapp", "0015_previous"), ] operations = [ migrations.RunPython(forwards, backwards), ]
from django.db.models.signals import post_save from django.dispatch import receiver @receiver(post_save, sender=User) def create_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance)
class AddressSerializer(serializers.ModelSerializer): class Meta: model = Address fields = ["street", "city", "country"] class UserSerializer(serializers.ModelSerializer): address = AddressSerializer() class Meta: model = User fields = ["name", "email", "address"] def create(self, validated_data): address_data = validated_data.pop("address") user = User.objects.create(**validated_data) Address.objects.create(user=user, **address_data) return user
from rest_framework.permissions import BasePermission class IsOwner(BasePermission): def has_object_permission(self, request, view, obj): return obj.owner == request.user
# settings.py REST_FRAMEWORK = { "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", "PAGE_SIZE": 25, } # Or custom pagination from rest_framework.pagination import CursorPagination class CreatedAtCursorPagination(CursorPagination): ordering = "-created_at" page_size = 50