Use Cursor's browser aria snapshots to audit a page for accessibility issues — missing labels, broken tab order, contrast, and ARIA misuse.
中文简介正在准备中。当前显示原文说明。
Django performance code review. Use when asked to "review Django performance", "find N+1 queries", "optimize Django", "check queryset performance", "database performance", "Django ORM issues", or audit Django code for performance problems.
中文简介正在准备中。当前显示原文说明。
查看安装方法安装前可以查看交给 AI 代理的指令内容。
Review Django code for validated performance issues. Research the codebase to confirm issues before reporting. Report only what you can prove.
Issues are organized by impact. Focus on CRITICAL and HIGH - these cause real problems at scale.
| Priority | Category | Impact |
|---|---|---|
| 1 | N+1 Queries | CRITICAL - Multiplies with data, causes timeouts |
| 2 | Unbounded Querysets | CRITICAL - Memory exhaustion, OOM kills |
| 3 | Missing Indexes | HIGH - Full table scans on large tables |
| 4 | Write Loops | HIGH - Lock contention, slow requests |
| 5 | Inefficient Patterns | LOW - Rarely worth reporting |
Impact: Each N+1 adds O(n) database round trips. 100 rows = 100 extra queries. 10,000 rows = timeout.
Validate by tracing: View → Queryset → Template/Serializer → Loop access
# PROBLEM: N+1 - each iteration queries profile
def user_list(request):
users = User.objects.all()
return render(request, 'users.html', {'users': users})
# Template:
# {% for user in users %}
# {{ user.profile.bio }} ← triggers query per user
# {% endfor %}
# SOLUTION: Prefetch in view
def user_list(request):
users = User.objects.select_related('profile')
return render(request, 'users.html', {'users': users})
DRF serializers accessing related fields cause N+1 if queryset isn't optimized.
# PROBLEM: SerializerMethodField queries per object
class UserSerializer(serializers.ModelSerializer):
order_count = serializers.SerializerMethodField()
def get_order_count(self, obj):
return obj.orders.count() # ← query per user
# SOLUTION: Annotate in viewset, access in serializer
class UserViewSet(viewsets.ModelViewSet):
def get_queryset(self):
return User.objects.annotate(order_count=Count('orders'))
class UserSerializer(serializers.ModelSerializer):
order_count = serializers.IntegerField(read_only=True)
# PROBLEM: Property triggers query when accessed
class User(models.Model):
@property
def recent_orders(self):
return self.orders.filter(created__gte=last_week)[:5]
# Used in template loop = N+1
# SOLUTION: Use Prefetch with custom queryset, or annotate
Impact: Loading entire tables exhausts memory. Large tables cause OOM kills and worker restarts.
# PROBLEM: No pagination - loads all rows
class UserListView(ListView):
model = User
template_name = 'users.html'
# SOLUTION: Add pagination
class UserListView(ListView):
model = User
template_name = 'users.html'
paginate_by = 25
# PROBLEM: Loads all objects into memory at once
for user in User.objects.all():
process(user)
# SOLUTION: Stream with iterator()
for user in User.objects.iterator(chunk_size=1000):
process(user)
# PROBLEM: Forces full evaluation into memory
all_users = list(User.objects.all())
# SOLUTION: Keep as queryset, slice if needed
users = User.objects.all()[:100]
Impact: Full table scans. Negligible on small tables, catastrophic on large ones.
# PROBLEM: Filtering on unindexed field
# User.objects.filter(email=email) # full scan if no index
class User(models.Model):
email = models.EmailField() # ← no db_index
# SOLUTION: Add index
class User(models.Model):
email = models.EmailField(db_index=True)
# PROBLEM: Sorting requires full scan without index
Order.objects.order_by('-created')
# SOLUTION: Index the sort field
class Order(models.Model):
created = models.DateTimeField(db_index=True)
class Order(models.Model):
user = models.ForeignKey(User)
status = models.CharField(max_length=20)
created = models.DateTimeField()
class Meta:
indexes = [
models.Index(fields=['user', 'status']), # for filter(user=x, status=y)
models.Index(fields=['status', '-created']), # for filter(status=x).order_by('-created')
]
Impact: N database writes instead of 1. Lock contention. Slow requests.
# PROBLEM: N inserts, N round trips
for item in items:
Model.objects.create(name=item['name'])
# SOLUTION: Single bulk insert
Model.objects.bulk_create([
Model(name=item['name']) for item in items
])
# PROBLEM: N updates
for obj in queryset:
obj.status = 'done'
obj.save()
# SOLUTION A: Single UPDATE statement (same value for all)
queryset.update(status='done')
# SOLUTION B: bulk_update (different values)
for obj in objects:
obj.status = compute_status(obj)
Model.objects.bulk_update(objects, ['status'], batch_size=500)
# PROBLEM: N deletes
for obj in queryset:
obj.delete()
# SOLUTION: Single DELETE
queryset.delete()
Rarely worth reporting. Include only as minor notes if you're already reporting real issues.
# Slightly suboptimal
if queryset.count() > 0:
do_thing()
# Marginally better
if queryset.exists():
do_thing()
Usually skip - difference is <1ms in most cases.
# Fetches all rows to count
if len(queryset) > 0: # bad if queryset not yet evaluated
# Single COUNT query
if queryset.count() > 0:
Only flag if queryset is large and not already evaluated.
# N queries, but if N is small (< 20), often fine
for id in ids:
obj = Model.objects.get(id=id)
Only flag if loop is large or this is in a very hot path.
Before reporting ANY issue:
If you cannot validate all steps, do not report.
## Django Performance Review: [File/Component Name]
### Summary
Validated issues: X (Y Critical, Z High)
### Findings
#### [PERF-001] N+1 Query in UserListView (CRITICAL)
**Location:** `views.py:45`
**Issue:** Related field `profile` accessed in template loop without prefetch.
**Validation:**
- Traced: UserListView → users queryset → user_list.html → `{{ user.profile.bio }}` in loop
- Searched codebase: no select_related('profile') found
- User table: 50k+ rows (verified in admin)
- Hot path: linked from homepage navigation
**Evidence:**
```python
def get_queryset(self):
return User.objects.filter(active=True) # no select_related
Fix:
def get_queryset(self):
return User.objects.filter(active=True).select_related('profile')
If no issues found: "No performance issues identified after reviewing [files] and validating [what you checked]."
**Before submitting, sanity check each finding:**
- Does the severity match the actual impact? ("Minor inefficiency" ≠ CRITICAL)
- Is this a real performance issue or just a style preference?
- Would fixing this measurably improve performance?
If the answer to any is "no" - remove the finding.
---
## What NOT to Report
- Test files
- Admin-only views
- Management commands
- Migration files
- One-time scripts
- Code behind disabled feature flags
- Tables with <1000 rows that won't grow
- Patterns in cold paths (rarely executed code)
- Micro-optimizations (exists vs count, only/defer without evidence)
### False Positives to Avoid
**Queryset variable assignment is not an issue:**
```python
# This is FINE - no performance difference
projects_qs = Project.objects.filter(org=org)
projects = list(projects_qs)
# vs this - identical performance
projects = list(Project.objects.filter(org=org))
Querysets are lazy. Assigning to a variable doesn't execute anything.
Single query patterns are not N+1:
# This is ONE query, not N+1
projects = list(Project.objects.filter(org=org))
N+1 requires a loop that triggers additional queries. A single list() call is fine.
Missing select_related on single object fetch is not N+1:
# This is 2 queries, not N+1 - report as LOW at most
state = AutofixState.objects.filter(pr_id=pr_id).first()
project_id = state.request.project_id # second query
N+1 requires a loop. A single object doing 2 queries instead of 1 can be reported as LOW if relevant, but never as CRITICAL/HIGH.
Style preferences are not performance issues: If your only suggestion is "combine these two lines" or "rename this variable" - that's style, not performance. Don't report it.
还没有评价。欢迎分享你的使用感受。
无需登录即可发表。欢迎分享使用感受、提问,或说明在哪些环境下无法运行。
还没有评论。来写第一条吧。
Use Cursor's browser aria snapshots to audit a page for accessibility issues — missing labels, broken tab order, contrast, and ARIA misuse.
中文简介正在准备中。当前显示原文说明。
Add PostHog analytics to a web application, including event tracking, page views, feature flags, and session replay.
中文简介正在准备中。当前显示原文说明。
Generate OpenAPI/Swagger documentation for an API, including endpoint schemas, request/response types, and interactive docs UI.
中文简介正在准备中。当前显示原文说明。
Add authentication to a web application using NextAuth.js (Auth.js), including OAuth providers, session management, and protected routes.
中文简介正在准备中。当前显示原文说明。
Dockerize an application with a production-ready Dockerfile, docker-compose setup, and .dockerignore.
中文简介正在准备中。当前显示原文说明。
Set up Playwright end-to-end testing in a project, including test configuration, example tests, and CI integration.
中文简介正在准备中。当前显示原文说明。