Skip to main content

django-orm-patterns

Use when Django ORM patterns with models, queries, and relationships. Use when building database-driven Django applications.

소스 정보

저장소
TheBushidoCollective/han
최근 소스 활동
2026년 2월 11일 17:47
감지된 SKILL.md 언어
영어
스타
198
포크
21

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
django-orm-patterns
user-invocable
false
description
Use when Django ORM patterns with models, queries, and relationships. Use when building database-driven Django applications.
allowed-tools
["Bash","Read"]
# Django ORM Patterns Master Django ORM for building efficient, scalable database-driven applications with complex queries and relationships. ## Model Definition Define models with proper field types, constraints, and metadata. ```python from django.db import models from django.core.validators import MinValueValidator, MaxValueValidator class User(models.Model): email = models.EmailField(unique=True, db_index=True) name = models.CharField(max_length=100) is_active = models.BooleanField(default=True) 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=['created_at', 'is_active']), ] verbose_name = 'User' verbose_name_plural = 'Users' def __str__(self): return self.email class Post(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE, related_name='posts') published = models.BooleanField(default=False) views = models.PositiveIntegerField(default=0) created_at = models.DateTimeField(auto_now_add=True) class Meta: ordering = ['-created_at'] indexes = [ models.Index(fields=['author', 'published']), ] ``` ## QuerySet API Basics Use Django's QuerySet API for efficient database queries. ```python # All records users = User.objects.all() # Filtering active_users = User.objects.filter(is_active=True) inactive_users = User.objects.exclude(is_active=True) # Get single record (raises exception if not found or multiple found) user = User.objects.get(email='user@example.com') # Get or create user, created = User.objects.get_or_create( email='user@example.com', defaults={'name': 'John Doe'} ) # Update or create user, created = User.objects.update_or_create( email='user@example.com', defaults={'name': 'Jane Doe', 'is_active': True} ) # Chaining filters posts = Post.objects.filter(published=True).filter(author__is_active=True) # Order by users = User.objects.order_by('-created_at', 'name') # Limit results recent_users = User.objects.all()[:10] # Count user_count = User.objects.filter(is_active=True).count() # Exists has_active_users = User.objects.filter(is_active=True).exists() ``` ## Q Objects for Complex Queries Build complex queries with Q objects for OR and NOT operations. ```python from django.db.models import Q # OR queries users = User.objects.filter( Q(name__icontains='john') | Q(email__icontains='john') ) # AND with OR users = User.objects.filter( Q(is_active=True) & (Q(name__icontains='john') | Q(email__icontains='john')) ) # NOT queries users = User.objects.filter(~Q(is_active=True)) # Complex combinations posts = Post.objects.filter( Q(published=True) & (Q(author__name__icontains='john') | Q(title__icontains='important')) & ~Q(views__lt=100) ) # Dynamic query building def search_users(name=None, email=None, is_active=None): query = Q() if name: query &= Q(name__icontains=name) if email: query &= Q(email__icontains=email) if is_active is not None: query &= Q(is_active=is_active) return User.objects.filter(query) ``` ## F Objects for Field References Use F objects to reference model fields in queries and updates. ```python from django.db.models import F # Compare fields posts = Post.objects.filter(views__gt=F('author__posts__count')) # Update based on current value Post.objects.filter(published=True).update(views=F('views') + 1) # Avoid race conditions post = Post.objects.get(id=1) post.views = F('views') + 1 post.save() post.refresh_from_db() # Get updated value # Complex expressions from django.db.models import ExpressionWrapper, IntegerField Post.objects.annotate( adjusted_views=ExpressionWrapper( F('views') * 2 + 10, output_field=IntegerField() ) ) ``` ## Aggregation and Annotation Perform database-level calculations and add computed fields. ```python from django.db.models import Count, Sum, Avg, Max, Min # Simple aggregation from django.db.models import Avg avg_views = Post.objects.aggregate(Avg('views')) # Returns: {'views__avg': 42.5} # Multiple aggregations stats = Post.objects.aggregate( total_posts=Count('id'), avg_views=Avg('views'), max_views=Max('views'), min_views=Min('views') ) # Annotation (adds field to each object) users = User.objects.annotate( post_count=Count('posts'), total_views=Sum('posts__views') ) for user in users: print(f"{user.name}: {user.post_count} posts, {user.total_views} views") # Filter by annotation popular_users = User.objects.annotate( post_count=Count('posts') ).filter(post_count__gt=10) # Complex annotations from django.db.models import Case, When, Value, CharField User.objects.annotate( user_type=Case( When(post_count__gt=10, then=Value('prolific')), When(post_count__gt=5, then=Value('active')), default=Value('casual'), output_field=CharField() ) ) ``` ## Prefetch and Select Related (N+1 Prevention) Optimize queries by reducing database hits with eager loading. ```python # Select related (for ForeignKey and OneToOne) posts = Post.objects.select_related('author').all() for post in posts: print(post.author.name) # No additional query # Prefetch related (for ManyToMany and reverse ForeignKey) from django.db.models import Prefetch users = User.objects.prefetch_related('posts').all() for user in users: for post in user.posts.all(): # No additional query print(post.title) # Custom prefetch users = User.objects.prefetch_related( Prefetch( 'posts', queryset=Post.objects.filter(published=True).order_by('-created_at') ) ) # Multiple levels posts = Post.objects.select_related( 'author' ).prefetch_related( 'author__posts' # Prefetch all posts by the same author ) # Combining both Post.objects.select_related('author').prefetch_related('tags') ``` ## Custom Managers and QuerySets Create reusable query logic with custom managers and querysets. ```python from django.db import models class PublishedQuerySet(models.QuerySet): def published(self): return self.filter(published=True) def recent(self): return self.order_by('-created_at')[:10] def by_author(self, author): return self.filter(author=author) class PublishedManager(models.Manager): def get_queryset(self): return PublishedQuerySet(self.model, using=self._db) def published(self): return self.get_queryset().published() def recent(self): return self.get_queryset().recent() class Post(models.Model): # fields... objects = models.Manager() # Default manager published_posts = PublishedManager() # Custom manager class Meta: base_manager_name = 'objects' # Usage Post.published_posts.published().recent() Post.published_posts.published().by_author(user) # Chaining custom methods class UserQuerySet(models.QuerySet): def active(self): return self.filter(is_active=True) def with_posts(self): return self.annotate(post_count=Count('posts')).filter(post_count__gt=0) User.objects.active().with_posts() ``` ## Transactions and Atomic Blocks Ensure data consistency with database transactions. ```python from django.db import transaction # Atomic decorator @transaction.atomic def create_user_with_post(email, name, post_title): user = User.objects.create(email=email, name=name) Post.objects.create(title=post_title, author=user) return user # Context manager def update_user_posts(user_id): try: with transaction.atomic(): user = User.objects.select_for_update().get(id=user_id) user.posts.update(published=True) user.is_active = True user.save() except Exception as e: # Transaction is rolled back raise # Savepoints from django.db import transaction with transaction.atomic(): user = User.objects.create(email='user@example.com') sid = transaction.savepoint() try: Post.objects.create(title='Test', author=user) except: transaction.savepoint_rollback(sid) else: transaction.savepoint_commit(sid) # Select for update (locking) with transaction.atomic(): user = User.objects.select_for_update().get(id=1) user.is_active = False user.save() ``` ## Advanced Select and Prefetch Patterns Master complex query optimization with advanced eager loading techniques. ```python from django.db.models import Prefetch, Count, Q # Basic select_related (ForeignKey, OneToOne) posts = Post.objects.select_related('author', 'category') # Multi-level select_related comments = Comment.objects.select_related('post__author__profile') # Prefetch with custom queryset users = User.objects.prefetch_related( Prefetch( 'posts', queryset=Post.objects.filter(published=True).select_related('category'), to_attr='published_posts' ) ) # Multiple prefetch with different filters authors = User.objects.prefetch_related( Prefetch( 'posts', queryset=Post.objects.filter(published=True), to_attr='published_posts' ), Prefetch( 'posts', queryset=Post.objects.filter(published=False), to_attr='draft_posts' ) ) # Nested prefetch posts = Post.objects.prefetch_related( Prefetch( 'comments', queryset=Comment.objects.select_related('author').prefetch_related( Prefetch( 'replies', queryset=Comment.objects.select_related('author') ) ) ) ) # Prefetch with annotations users = User.objects.prefetch_related( Prefetch( 'posts', queryset=Post.objects.annotate( comment_count=Count('comments') ).filter(comment_count__gt=0) ) ) ``` ## Database Functions and Expressions Leverage database functions for complex operations. ```python from django.db.models import F, Value, CharField, Case, When, Q from django.db.models.functions import Concat, Lower, Upper, Length, Substr, Coalesce # String operations users = User.objects.annotate( full_name=Concat('first_name', Value(' '), 'last_name') ) users = User.objects.annotate( email_lower=Lower('email'), name_upper=Upper('name') ) # String functions posts = Post.objects.annotate( title_length=Length('title') ).filter(title_length__gt=50) # Substring posts = Post.objects.annotate( title_preview=Substr('title', 1, 50) ) # Coalesce (return first non-null value) posts = Post.objects.annotate( display_name=Coalesce('custom_title', 'title', Value('Untitled')) ) # Date functions from django.db.models.functions import TruncDate, TruncMonth, ExtractYear, Now posts = Post.objects.annotate( created_date=TruncDate('created_at'), created_month=TruncMonth('created_at'), created_year=ExtractYear('created_at') ) # Date arithmetic from datetime import timedelta from django.utils import timezone recent_posts = Post.objects.filter( created_at__gte=timezone.now() - timedelta(days=7) ) # Mathematical functions from django.db.models.functions import Abs, Ceil, Floor, Round products = Product.objects.annotate(
GitHub에서 보기
이 SKILL.md는 매우 커서 SkillsMP가 여기에는 첫 섹션만 미리 보여줍니다. GitHub에서 보기