django-application
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDjango Application
Django 应用程序
Overview
概述
Build comprehensive Django web applications with proper model design, view hierarchies, database operations, user authentication, and admin functionality following Django conventions and best practices.
遵循Django规范和最佳实践,构建包含合理模型设计、视图层级、数据库操作、用户身份验证和管理功能的全面Django Web应用程序。
When to Use
适用场景
- Creating Django web applications
- Designing models and database schemas
- Implementing views and URL routing
- Building authentication systems
- Using Django ORM for database operations
- Creating admin interfaces and dashboards
- 创建Django Web应用程序
- 设计模型和数据库架构
- 实现视图和URL路由
- 构建身份验证系统
- 使用Django ORM进行数据库操作
- 创建管理界面和仪表板
Instructions
操作步骤
1. Django Project Setup
1. Django 项目搭建
bash
django-admin startproject myproject
cd myproject
python manage.py startapp users
python manage.py startapp productsbash
django-admin startproject myproject
cd myproject
python manage.py startapp users
python manage.py startapp products2. Model Design with ORM
2. 基于ORM的模型设计
python
undefinedpython
undefinedusers/models.py
users/models.py
from django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model
class CustomUser(AbstractUser):
ROLE_CHOICES = [
('admin', 'Administrator'),
('user', 'Regular User'),
]
profile_picture = models.ImageField(upload_to='profiles/', null=True)
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user')
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=['role']),
]
def __str__(self):
return self.emailfrom django.contrib.auth.models import AbstractUser
from django.db import models
from django.contrib.auth import get_user_model
class CustomUser(AbstractUser):
ROLE_CHOICES = [
('admin', 'Administrator'),
('user', 'Regular User'),
]
profile_picture = models.ImageField(upload_to='profiles/', null=True)
role = models.CharField(max_length=20, choices=ROLE_CHOICES, default='user')
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=['role']),
]
def __str__(self):
return self.emailproducts/models.py
products/models.py
User = get_user_model()
class Product(models.Model):
STATUS_CHOICES = [
('draft', 'Draft'),
('published', 'Published'),
]
title = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='products')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
unique_together = ['slug', 'owner']
def __str__(self):
return self.titleclass ProductReview(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)])
comment = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ['product', 'author']undefinedUser = get_user_model()
class Product(models.Model):
STATUS_CHOICES = [
('draft', 'Draft'),
('published', 'Published'),
]
title = models.CharField(max_length=200, db_index=True)
slug = models.SlugField(unique=True)
description = models.TextField()
price = models.DecimalField(max_digits=10, decimal_places=2)
stock = models.PositiveIntegerField(default=0)
status = models.CharField(max_length=10, choices=STATUS_CHOICES, default='draft')
owner = models.ForeignKey(User, on_delete=models.CASCADE, related_name='products')
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Meta:
ordering = ['-created_at']
unique_together = ['slug', 'owner']
def __str__(self):
return self.titleclass ProductReview(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE, related_name='reviews')
author = models.ForeignKey(User, on_delete=models.CASCADE)
rating = models.IntegerField(choices=[(i, i) for i in range(1, 6)])
comment = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
class Meta:
unique_together = ['product', 'author']undefined3. Views with Class-Based and Function-Based Approaches
3. 基于类和函数的视图实现
python
undefinedpython
undefinedproducts/views.py
products/views.py
from django.views import View
from django.views.generic import ListView, DetailView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from django.db.models import Q, Count, Avg
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from .models import Product, ProductReview
from .serializers import ProductSerializer
from django.views import View
from django.views.generic import ListView, DetailView, CreateView
from django.contrib.auth.mixins import LoginRequiredMixin
from django.shortcuts import render, redirect, get_object_or_404
from django.http import JsonResponse
from django.db.models import Q, Count, Avg
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.decorators import action
from rest_framework.permissions import IsAuthenticated
from .models import Product, ProductReview
from .serializers import ProductSerializer
Class-based view with authentication
带身份验证的类视图
class ProductListView(LoginRequiredMixin, ListView):
model = Product
template_name = 'products/list.html'
context_object_name = 'products'
paginate_by = 20
def get_queryset(self):
queryset = Product.objects.filter(status='published')
# Search and filter
search = self.request.GET.get('q')
if search:
queryset = queryset.filter(
Q(title__icontains=search) | Q(description__icontains=search)
)
# Price range filter
min_price = self.request.GET.get('min_price')
max_price = self.request.GET.get('max_price')
if min_price:
queryset = queryset.filter(price__gte=min_price)
if max_price:
queryset = queryset.filter(price__lte=max_price)
return queryset.annotate(
review_count=Count('reviews'),
avg_rating=Avg('reviews__rating')
).order_by('-created_at')class ProductListView(LoginRequiredMixin, ListView):
model = Product
template_name = 'products/list.html'
context_object_name = 'products'
paginate_by = 20
def get_queryset(self):
queryset = Product.objects.filter(status='published')
# 搜索和过滤
search = self.request.GET.get('q')
if search:
queryset = queryset.filter(
Q(title__icontains=search) | Q(description__icontains=search)
)
# 价格范围过滤
min_price = self.request.GET.get('min_price')
max_price = self.request.GET.get('max_price')
if min_price:
queryset = queryset.filter(price__gte=min_price)
if max_price:
queryset = queryset.filter(price__lte=max_price)
return queryset.annotate(
review_count=Count('reviews'),
avg_rating=Avg('reviews__rating')
).order_by('-created_at')REST API ViewSet
REST API 视图集
class ProductViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = ProductSerializer
queryset = Product.objects.all()
def get_queryset(self):
return Product.objects.filter(owner=self.request.user)
@action(detail=True, methods=['post'])
def add_review(self, request, pk=None):
product = self.get_object()
serializer = ProductReviewSerializer(data=request.data)
if serializer.is_valid():
serializer.save(product=product, author=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['get'])
def reviews(self, request, pk=None):
product = self.get_object()
reviews = product.reviews.all()
serializer = ProductReviewSerializer(reviews, many=True)
return Response(serializer.data)undefinedclass ProductViewSet(viewsets.ModelViewSet):
permission_classes = [IsAuthenticated]
serializer_class = ProductSerializer
queryset = Product.objects.all()
def get_queryset(self):
return Product.objects.filter(owner=self.request.user)
@action(detail=True, methods=['post'])
def add_review(self, request, pk=None):
product = self.get_object()
serializer = ProductReviewSerializer(data=request.data)
if serializer.is_valid():
serializer.save(product=product, author=request.user)
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
@action(detail=True, methods=['get'])
def reviews(self, request, pk=None):
product = self.get_object()
reviews = product.reviews.all()
serializer = ProductReviewSerializer(reviews, many=True)
return Response(serializer.data)undefined4. Authentication and Permissions
4. 身份验证与权限控制
python
undefinedpython
undefinedusers/views.py
users/views.py
from django.contrib.auth import authenticate, login, logout
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_protect
from rest_framework.authtoken.models import Token
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
def has_object_permission(self, request, view, obj):
return obj.owner == request.user
@require_http_methods(['POST'])
@csrf_protect
def login_view(request):
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
token, created = Token.objects.get_or_create(user=user)
return JsonResponse({
'success': True,
'token': token.key,
'user_id': user.id
})
return JsonResponse({'error': 'Invalid credentials'}, status=401)@require_http_methods(['POST'])
def logout_view(request):
logout(request)
return JsonResponse({'success': True})
undefinedfrom django.contrib.auth import authenticate, login, logout
from django.views.decorators.http import require_http_methods
from django.views.decorators.csrf import csrf_protect
from rest_framework.authtoken.models import Token
from rest_framework.permissions import BasePermission
class IsOwner(BasePermission):
def has_object_permission(self, request, view, obj):
return obj.owner == request.user
@require_http_methods(['POST'])
@csrf_protect
def login_view(request):
email = request.POST.get('email')
password = request.POST.get('password')
user = authenticate(request, username=email, password=password)
if user is not None:
login(request, user)
token, created = Token.objects.get_or_create(user=user)
return JsonResponse({
'success': True,
'token': token.key,
'user_id': user.id
})
return JsonResponse({'error': 'Invalid credentials'}, status=401)@require_http_methods(['POST'])
def logout_view(request):
logout(request)
return JsonResponse({'success': True})
undefined5. Database Queries and Optimization
5. 数据库查询与优化
python
undefinedpython
undefinedproducts/queries.py
products/queries.py
from django.db.models import Q, Count, Avg, F, Case, When, Value
from django.db.models.functions import Coalesce
from .models import Product, ProductReview
from django.db.models import Q, Count, Avg, F, Case, When, Value
from django.db.models.functions import Coalesce
from .models import Product, ProductReview
Optimized queries with select_related and prefetch_related
使用select_related和prefetch_related优化查询
def get_product_details(product_id):
return Product.objects.select_related('owner').prefetch_related(
'reviews__author'
).get(id=product_id)
def get_product_details(product_id):
return Product.objects.select_related('owner').prefetch_related(
'reviews__author'
).get(id=product_id)
Aggregation queries
聚合查询
def get_top_products():
return Product.objects.annotate(
review_count=Count('reviews'),
avg_rating=Avg('reviews__rating'),
total_reviews=Count('reviews', distinct=True)
).filter(review_count__gt=0).order_by('-avg_rating')[:10]
def get_top_products():
return Product.objects.annotate(
review_count=Count('reviews'),
avg_rating=Avg('reviews__rating'),
total_reviews=Count('reviews', distinct=True)
).filter(review_count__gt=0).order_by('-avg_rating')[:10]
Complex filtering
复杂过滤
def search_products(query, category=None, min_price=None, max_price=None):
queryset = Product.objects.filter(
Q(title__icontains=query) | Q(description__icontains=query)
)
if category:
queryset = queryset.filter(category=category)
if min_price:
queryset = queryset.filter(price__gte=min_price)
if max_price:
queryset = queryset.filter(price__lte=max_price)
return queryset.select_related('owner')def search_products(query, category=None, min_price=None, max_price=None):
queryset = Product.objects.filter(
Q(title__icontains=query) | Q(description__icontains=query)
)
if category:
queryset = queryset.filter(category=category)
if min_price:
queryset = queryset.filter(price__gte=min_price)
if max_price:
queryset = queryset.filter(price__lte=max_price)
return queryset.select_related('owner')Bulk operations
批量操作
def bulk_update_stock(updates):
products_to_update = []
for product_id, new_stock in updates.items():
product = Product.objects.get(id=product_id)
product.stock = new_stock
products_to_update.append(product)
Product.objects.bulk_update(products_to_update, ['stock'])undefineddef bulk_update_stock(updates):
products_to_update = []
for product_id, new_stock in updates.items():
product = Product.objects.get(id=product_id)
product.stock = new_stock
products_to_update.append(product)
Product.objects.bulk_update(products_to_update, ['stock'])undefined6. URL Routing
6. URL路由配置
python
undefinedpython
undefinedmyproject/urls.py
myproject/urls.py
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework.authtoken.views import obtain_auth_token
from products.views import ProductViewSet
router = DefaultRouter()
router.register(r'products', ProductViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
path('api-token-auth/', obtain_auth_token),
]
undefinedfrom django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from rest_framework.authtoken.views import obtain_auth_token
from products.views import ProductViewSet
router = DefaultRouter()
router.register(r'products', ProductViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
path('api-token-auth/', obtain_auth_token),
]
undefined7. Admin Interface Customization
7. 管理界面定制
python
undefinedpython
undefinedproducts/admin.py
products/admin.py
from django.contrib import admin
from .models import Product, ProductReview
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ['title', 'price', 'stock', 'status', 'owner', 'created_at']
list_filter = ['status', 'created_at', 'owner']
search_fields = ['title', 'description']
readonly_fields = ['created_at', 'updated_at']
fieldsets = (
('Basic Info', {
'fields': ('title', 'slug', 'owner')
}),
('Details', {
'fields': ('description', 'price', 'stock', 'status')
}),
('Metadata', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def save_model(self, request, obj, form, change):
if not change:
obj.owner = request.user
super().save_model(request, obj, form, change)@admin.register(ProductReview)
class ProductReviewAdmin(admin.ModelAdmin):
list_display = ['product', 'author', 'rating', 'created_at']
list_filter = ['rating', 'created_at']
readonly_fields = ['created_at']
undefinedfrom django.contrib import admin
from .models import Product, ProductReview
@admin.register(Product)
class ProductAdmin(admin.ModelAdmin):
list_display = ['title', 'price', 'stock', 'status', 'owner', 'created_at']
list_filter = ['status', 'created_at', 'owner']
search_fields = ['title', 'description']
readonly_fields = ['created_at', 'updated_at']
fieldsets = (
('Basic Info', {
'fields': ('title', 'slug', 'owner')
}),
('Details', {
'fields': ('description', 'price', 'stock', 'status')
}),
('Metadata', {
'fields': ('created_at', 'updated_at'),
'classes': ('collapse',)
}),
)
def save_model(self, request, obj, form, change):
if not change:
obj.owner = request.user
super().save_model(request, obj, form, change)@admin.register(ProductReview)
class ProductReviewAdmin(admin.ModelAdmin):
list_display = ['product', 'author', 'rating', 'created_at']
list_filter = ['rating', 'created_at']
readonly_fields = ['created_at']
undefinedBest Practices
最佳实践
✅ DO
✅ 建议做法
- Use models for database operations
- Implement proper indexes on frequently queried fields
- Use select_related and prefetch_related for query optimization
- Implement authentication and permissions
- Use Django Forms for form validation
- Cache expensive queries
- Use management commands for batch operations
- Implement logging for debugging
- Use middleware for cross-cutting concerns
- Validate user input
- 使用模型进行数据库操作
- 在频繁查询的字段上创建合适的索引
- 使用select_related和prefetch_related优化查询
- 实现身份验证和权限控制
- 使用Django Forms进行表单验证
- 缓存开销大的查询
- 使用管理命令执行批量操作
- 实现日志记录用于调试
- 使用中间件处理横切关注点
- 验证用户输入
❌ DON'T
❌ 避免做法
- Use raw SQL without ORM
- N+1 query problems without optimization
- Store secrets in code
- Trust user input directly
- Override init in models unnecessarily
- Make synchronous heavy operations in views
- Use inheritance models unless necessary
- Expose stack traces in production
- 不使用ORM而直接编写原生SQL
- 不进行优化导致N+1查询问题
- 在代码中存储敏感信息
- 直接信任用户输入
- 不必要地在模型中重写__init__方法
- 在视图中执行同步的重量级操作
- 除非必要否则不使用模型继承
- 在生产环境中暴露堆栈跟踪
Complete Example
完整示例
python
undefinedpython
undefinedsettings.py
settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'rest_framework',
'users',
'products'
]
AUTH_USER_MODEL = 'users.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'rest_framework',
'users',
'products'
]
AUTH_USER_MODEL = 'users.CustomUser'
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
]
}
models.py + views.py (see sections above)
models.py + views.py (参考上述章节)
urls.py + admin.py (see sections above)
urls.py + admin.py (参考上述章节)
undefinedundefined