Django模式
Mattakushi4322026-10-25查看 45复制 882
何时激活:Django、Django ORM、DRF、视图、序列化器、迁移、Django 管理、基于类的视图
📘如何使用这个技能
- 1复制技能内容·点击上方「Copy SKILL.md」复制全部内容,或 Download 下载到本地
- 2打开你的 AI 客户端·支持 Claude Code、Trae、Cursor、ChatGPT、DeepSeek、Kimi 等任意 AI 助手
- 3粘贴为系统提示/知识文件·Claude Code:放入 .claude/skills/ 目录;普通对话:作为首条消息发送并说「请严格按这份技能文档执行」
- 4直接提出你的需求·AI 会按技能定义的工作流、格式和约束来处理,无需再解释背景
💡 提示:技能生效后,每次对话只需一句需求,AI 会按 SKILL.md 的流程执行。
SKILL.md4279 chars
---
name: django-patterns
description: "When to activate: Django, Django ORM, DRF, views, serializers, migrations, Django admin, class-based views"
origin: zakr
metadata:
namespace: zakr/devtools-pack
version: 1.0.0
category: engineering
language: python
platforms: [claude-code, codex, gemini-cli, cursor, aider, windsurf]
---
# Django Patterns
## Project Layout
```
myproject/
├── config/
│ ├── settings/
│ │ ├── base.py
│ │ ├── development.py
│ │ └── production.py
│ ├── urls.py
│ └── wsgi.py
├── apps/
│ ├── users/
│ │ ├── models.py
│ │ ├── views.py
│ │ ├── serializers.py
│ │ ├── urls.py
│ │ ├── admin.py
│ │ └── tests/
│ └── orders/
└── manage.py
```
## Model Best Practices
```python
from django.db import models
from django.contrib.auth import get_user_model
User = get_user_model() # always use get_user_model(), not direct import
class TimestampedModel(models.Model):
"""Abstract base for created_at/updated_at."""
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Order(TimestampedModel):
user = models.ForeignKey(User, on_delete=models.PROTECT, related_name="orders")
status = models.CharField(
max_length=20,
choices=[("pending", "Pending"), ("complete", "Complete"), ("cancelled", "Cancelled")],
default="pending",
db_index=True,
)
total_amount = models.DecimalField(max_digits=10, decimal_places=2)
class Meta:
ordering = ["-created_at"]
indexes = [models.Index(fields=["user", "status"])]
def __str__(self) -> str:
return f"Order #{self.pk} ({self.status})"
```
## DRF Serializers
```python
from rest_framework import serializers
class OrderSerializer(serializers.ModelSerializer):
user_name = serializers.CharField(source="user.full_name", read_only=True)
class Meta:
model = Order
fields = ["id", "user_name", "status", "total_amount", "created_at"]
read_only_fields = ["id", "created_at"]
def validate_total_amount(self, value):
if value <= 0:
raise serializers.ValidationError("Amount must be positive")
return value
class OrderCreateSerializer(serializers.ModelSerializer):
class Meta:
model = Order
fields = ["status", "total_amount"]
def create(self, validated_data):
validated_data["user"] = self.context["request"].user
return super().create(validated_data)
```
## DRF ViewSets
```python
from rest_framework import viewsets, permissions, filters
from django_filters.rest_framework import DjangoFilterBackend
class OrderViewSet(viewsets.ModelViewSet):
permission_classes = [permissions.IsAuthenticated]
filter_backends = [DjangoFilterBackend, filters.OrderingFilter]
filterset_fields = ["status"]
ordering_fields = ["created_at", "total_amount"]
ordering = ["-created_at"]
def get_queryset(self):
# Always scope to current user
return Order.objects.filter(user=self.request.user).select_related("user")
def get_serializer_class(self):
if self.action == "create":
return OrderCreateSerializer
return OrderSerializer
```
## Database Optimization
```python
# Avoid N+1 with select_related (FK) and prefetch_related (M2M/reverse FK)
orders = Order.objects.filter(status="pending")\
.select_related("user")\
.prefetch_related("items__product")\
.only("id", "status", "created_at", "user__email") # only needed fields
# Bulk operations
Order.objects.bulk_create([Order(**data) for data in order_data_list], batch_size=500)
Order.objects.filter(status="pending").update(status="processing") # no Python loop
# Use values() for read-only aggregations
from django.db.models import Count, Avg
stats = Order.objects.values("status").annotate(count=Count("id"), avg=Avg("total_amount"))
```
## Anti-Patterns
- Calling `Model.objects.all()` without `.filter()` on large tables
- N+1 queries — always check Django Debug Toolbar
- Logic in templates or views instead of model methods
- `on_delete=models.CASCADE` without thinking about consequences
- Missing `select_related` in list views