1. Django框架概述:为什么选择它?
Django是一个基于Python的高级Web框架,它遵循"不重复自己"(DRY)原则和"约定优于配置"(CoC)理念。我第一次接触Django是在2012年,当时正在寻找一个能快速构建内容管理系统的解决方案。相比其他框架,Django最吸引我的是它的"全栈"特性——开箱即用的Admin后台、ORM系统、模板引擎和URL路由等组件一应俱全。
Django的核心优势在于其"电池内置"(Batteries-included)哲学。这意味着开发者不需要花费大量时间集成第三方库来完成基础功能。例如,用户认证系统只需几行代码就能实现完整功能,这在其他框架中往往需要自行开发或集成多个库。我在实际项目中发现,这种设计理念特别适合中小型Web应用的快速开发。
提示:Django的Admin后台是其杀手级功能之一,对于需要快速搭建管理界面的项目可以节省大量开发时间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Django项目结构与核心组件
2.1 标准项目目录解析
一个典型的Django项目结构如下:
code复制myproject/
├── manage.py # 项目管理脚本
├── myproject/ # 项目配置目录
│ ├── __init__.py
│ ├── settings.py # 项目设置
│ ├── urls.py # 主URL配置
│ └── wsgi.py # WSGI配置
└── myapp/ # 应用目录
├── migrations/ # 数据库迁移文件
├── __init__.py
├── admin.py # Admin配置
├── apps.py # 应用配置
├── models.py # 数据模型
├── tests.py # 测试用例
├── urls.py # 应用URL配置
└── views.py # 视图函数
这种结构设计体现了Django的模块化思想。我在多个项目中实践发现,合理的项目结构划分能显著提高代码可维护性。例如,建议将大型项目拆分为多个应用(app),每个应用专注于特定功能模块。
2.2 核心组件工作流程
Django遵循MTV(Model-Template-View)模式,其工作流程可以概括为:
- 用户请求到达URL路由器
- 路由器匹配对应视图函数
- 视图通过模型与数据库交互
- 视图渲染模板并返回响应
这个过程中最值得关注的是Django的中间件系统。我在实际开发中经常自定义中间件来处理跨域、权限验证等通用逻辑。例如,一个简单的日志记录中间件可以这样实现:
python复制class LoggingMiddleware:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
# 请求处理前逻辑
start_time = time.time()
response = self.get_response(request)
# 请求处理后逻辑
duration = time.time() - start_time
log_entry = f"{request.method} {request.path} {response.status_code} {duration:.2f}s"
logger.info(log_entry)
return response
3. Django ORM深度解析
3.1 模型定义与关系处理
Django的ORM(Object-Relational Mapping)系统是其最强大的功能之一。它允许开发者用Python类定义数据模型,而无需直接编写SQL。例如,定义一个博客系统的模型:
python复制from django.db import models
class Author(models.Model):
name = models.CharField(max_length=100)
email = models.EmailField(unique=True)
bio = models.TextField()
class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
published_date = models.DateTimeField(auto_now_add=True)
author = models.ForeignKey(Author, on_delete=models.CASCADE)
tags = models.ManyToManyField('Tag')
class Tag(models.Model):
name = models.CharField(max_length=50, unique=True)
在实际项目中,我总结了几条ORM使用经验:
- 使用
select_related优化外键查询 - 对于多对多关系,
prefetch_related能显著减少查询次数 - 避免在循环中执行数据库查询(N+1问题)
- 合理使用
only()和defer()控制字段加载
3.2 查询优化实战技巧
Django ORM的查询集(QuerySet)是惰性执行的,这意味着我们可以链式调用多个方法而不立即访问数据库。例如:
python复制# 不会立即查询数据库
queryset = Post.objects.filter(
published_date__year=2023
).exclude(
title__startswith='Draft'
).select_related('author')
# 此时才会真正执行查询
posts = list(queryset)
我在性能敏感的项目中发现,ORM的explain()方法非常有用,它可以显示查询的执行计划:
python复制print(Post.objects.filter(author__name='John').explain())
注意:在生产环境中,数据库索引的合理设置对性能影响巨大。建议为常用查询字段添加索引,例如:
python复制class Post(models.Model): title = models.CharField(max_length=200, db_index=True) # ...
4. Django实战:构建REST API
4.1 DRF(Django REST Framework)基础
虽然Django本身可以处理API请求,但使用DRF能更高效地构建RESTful接口。安装DRF后,我们可以快速创建序列化器和视图:
python复制# serializers.py
from rest_framework import serializers
from .models import Post
class PostSerializer(serializers.ModelSerializer):
class Meta:
model = Post
fields = ['id', 'title', 'content', 'published_date', 'author']
read_only_fields = ['published_date']
# views.py
from rest_framework import generics
from .models import Post
from .serializers import PostSerializer
class PostListCreateView(generics.ListCreateAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
class PostRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView):
queryset = Post.objects.all()
serializer_class = PostSerializer
在实际项目中,我通常会添加以下功能:
- 分页(Pagination)
- 限流(Rate Limiting)
- JWT认证
- API文档(Swagger/Redoc)
4.2 性能优化进阶
对于高并发API,我总结了几点优化经验:
-
缓存策略:使用Django的缓存框架或Redis
python复制from django.core.cache import cache def get_popular_posts(): key = 'popular_posts' result = cache.get(key) if not result: result = list(Post.objects.filter(...)) cache.set(key, result, timeout=3600) return result -
异步任务:使用Celery处理耗时操作
python复制@shared_task def process_post_analytics(post_id): post = Post.objects.get(id=post_id) # 耗时分析逻辑 post.save() -
数据库读写分离:配置多个数据库路由
python复制class PrimaryReplicaRouter: def db_for_read(self, model, **hints): return 'replica' def db_for_write(self, model, **hints): return 'primary'
5. Django部署与运维实践
5.1 生产环境配置要点
从开发到生产环境,有几个关键配置需要调整:
python复制# settings.py
# 安全配置
DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
SECURE_SSL_REDIRECT = True
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
# 静态文件
STATIC_ROOT = '/var/www/static/'
STATIC_URL = '/static/'
# 数据库
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydatabase',
'USER': 'mydatabaseuser',
'PASSWORD': 'mypassword',
'HOST': '127.0.0.1',
'PORT': '5432',
}
}
我在部署过程中遇到的常见问题包括:
- 静态文件收集问题(记得运行
collectstatic) - 数据库迁移冲突(团队协作时特别容易出现)
- 时区设置不一致导致的时间显示问题
5.2 性能监控与调优
对于线上Django应用,我通常会配置以下监控:
- 使用django-debug-toolbar进行本地调试
- 配置Sentry错误监控
- 使用Prometheus+Grafana监控系统指标
- 数据库慢查询日志分析
一个实用的性能优化技巧是使用django-silk进行请求分析:
python复制# 安装后配置中间件
MIDDLEWARE = [
...
'silk.middleware.SilkyMiddleware',
...
]
在大型项目中,我还发现合理使用Django的信号系统(Signals)能解耦代码:
python复制from django.db.models.signals import post_save
from django.dispatch import receiver
from .models import Post
@receiver(post_save, sender=Post)
def update_post_index(sender, instance, **kwargs):
# 更新搜索引擎索引
...
6. Django生态与扩展
Django强大的生态系统是其长期保持活力的关键。以下是我在项目中经常使用的一些优秀第三方包:
- 用户认证:django-allauth(支持社交账号登录)
- 表单处理:django-crispy-forms(美化表单展示)
- 内容管理:django-ckeditor(富文本编辑器)
- 任务队列:django-celery-beat(定时任务)
- 搜索引擎:django-haystack(全文搜索)
- API文档:drf-yasg(Swagger集成)
在选择第三方包时,我的经验法则是:
- 查看最近更新时间(确保维护活跃)
- 检查开源协议(避免商业风险)
- 评估社区支持(GitHub stars/issues)
- 测试与当前Django版本的兼容性
例如,集成django-allauth的基本步骤:
python复制# settings.py
INSTALLED_APPS = [
...
'allauth',
'allauth.account',
'allauth.socialaccount',
# 提供者如Google、Facebook
'allauth.socialaccount.providers.google',
...
]
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
# urls.py
urlpatterns = [
...
path('accounts/', include('allauth.urls')),
...
]
7. Django测试与安全
7.1 测试策略与实践
Django内置了强大的测试框架,支持多种测试类型:
python复制from django.test import TestCase
from .models import Author
class AuthorModelTest(TestCase):
@classmethod
def setUpTestData(cls):
# 设置测试数据
Author.objects.create(name='Test Author', email='author@example.com')
def test_name_label(self):
author = Author.objects.get(id=1)
field_label = author._meta.get_field('name').verbose_name
self.assertEqual(field_label, 'name')
def test_name_max_length(self):
author = Author.objects.get(id=1)
max_length = author._meta.get_field('name').max_length
self.assertEqual(max_length, 100)
在实际项目中,我建议采用分层测试策略:
- 单元测试:覆盖模型、工具函数等独立单元
- 集成测试:验证组件间交互
- E2E测试:使用Selenium等工具模拟用户操作
7.2 安全最佳实践
Django虽然内置了许多安全特性,但仍需开发者注意:
-
SQL注入防护:始终使用ORM或参数化查询
python复制# 错误做法 query = f"SELECT * FROM posts WHERE title = '{user_input}'" # 正确做法 Post.objects.filter(title=user_input) -
XSS防护:模板系统自动转义,但需注意
mark_safe的使用html复制<!-- 自动转义 --> <div>{{ user_content }}</div> <!-- 需要特别小心 --> <div>{{ user_content|safe }}</div> -
CSRF防护:确保表单包含
{% csrf_token %} -
文件上传安全:
- 验证文件类型(不要依赖扩展名)
- 限制文件大小
- 将上传文件存储在非Web根目录
我在实际项目中遇到过文件上传漏洞导致的服务器安全问题,后来采用了以下防护措施:
python复制# 自定义文件验证
from django.core.exceptions import ValidationError
def validate_file_extension(value):
import os
ext = os.path.splitext(value.name)[1]
valid_extensions = ['.jpg', '.png', '.pdf']
if not ext.lower() in valid_extensions:
raise ValidationError('Unsupported file extension.')
8. Django与现代前端集成
8.1 前后端分离架构
虽然Django可以处理前后端,但现代项目更倾向于前后端分离。我的经验是:
-
API模式:Django作为纯后端提供REST/GraphQL API
- 前端使用React/Vue等框架
- 通过axios等库调用API
- 需要处理CORS问题
-
混合模式:Django模板渲染基础页面,前端框架处理交互
- 适合渐进式增强的项目
- 可以使用Django的静态文件处理
-
微前端架构:将前端拆分为多个独立模块
- 适合大型复杂应用
- 需要更复杂的构建配置
8.2 Django与Vue集成示例
一个简单的集成方案是在Django中提供Vue所需的静态文件:
-
在Django项目中创建前端目录:
code复制frontend/ ├── src/ │ ├── App.vue │ ├── main.js │ └── components/ ├── package.json └── vite.config.js -
配置Vue构建输出到Django的静态目录:
javascript复制// vite.config.js export default defineConfig({ build: { outDir: '../static/dist', emptyOutDir: true, } }) -
在Django模板中引入构建结果:
html复制{% load static %} <!DOCTYPE html> <html> <head> <title>My Django-Vue App</title> </head> <body> <div id="app"></div> <script src="{% static 'dist/assets/index.js' %}"></script> </body> </html>
在实际项目中,我通常会配置Webpack/Vite的代理,使前端开发服务器能直接访问Django的API,避免跨域问题:
javascript复制// vite.config.js
export default defineConfig({
server: {
proxy: {
'/api': {
target: 'http://localhost:8000',
changeOrigin: true,
}
}
}
})
9. Django项目架构进阶
9.1 大型项目组织结构
对于企业级应用,合理的项目结构至关重要。我参与的一个电商项目采用了如下结构:
code复制ecommerce/
├── apps/
│ ├── accounts/ # 用户账户
│ ├── products/ # 商品管理
│ ├── orders/ # 订单处理
│ └── payments/ # 支付集成
├── config/ # 项目配置
│ ├── settings/
│ │ ├── base.py
│ │ ├── dev.py
│ │ └── prod.py
│ └── urls.py
├── libs/ # 共享库
├── static/
├── templates/
└── manage.py
这种结构的优势在于:
- 按功能划分应用,职责单一
- 配置环境分离,安全敏感配置不上传Git
- 共享代码集中管理
- 模板和静态文件统一存放
9.2 领域驱动设计(DDD)实践
在复杂业务系统中,我尝试将DDD原则应用于Django项目:
-
分层架构:
- 表现层:Views、Serializers
- 应用层:服务类、用例实现
- 领域层:业务逻辑、领域模型
- 基础设施层:数据库、外部服务集成
-
领域模型示例:
python复制# orders/models.py class Order(models.Model): PENDING = 'pending' PAID = 'paid' STATUS_CHOICES = [ (PENDING, 'Pending'), (PAID, 'Paid'), ] user = models.ForeignKey(User, on_delete=models.PROTECT) status = models.CharField(max_length=20, choices=STATUS_CHOICES, default=PENDING) total = models.DecimalField(max_digits=10, decimal_places=2) def mark_as_paid(self): if self.status != self.PENDING: raise ValueError("Only pending orders can be marked as paid") self.status = self.PAID self.save() self.send_confirmation_email() def send_confirmation_email(self): # 发送邮件逻辑 ... -
服务层示例:
python复制# orders/services.py class OrderService: @classmethod def create_order(cls, user, items): total = sum(item.price for item in items) order = Order.objects.create(user=user, total=total) for item in items: OrderItem.objects.create( order=order, product=item.product, quantity=item.quantity, price=item.price ) payment = PaymentService.create_payment(order) return order, payment
这种架构虽然增加了初期复杂度,但在长期维护和业务扩展时优势明显,特别适合团队协作的大型项目。
10. Django性能调优实战
10.1 数据库优化进阶
除了基本的查询优化,我在高负载系统中还采用了以下策略:
-
读写分离:
python复制# settings.py DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'primary_db', # ... }, 'replica': { 'ENGINE': 'django.db.backends.postgresql', 'NAME': 'replica_db', # ... } } # database_router.py class PrimaryReplicaRouter: def db_for_read(self, model, **hints): return 'replica' def db_for_write(self, model, **hints): return 'default' -
连接池管理:
使用django-db-geventpool优化连接管理:python复制DATABASES = { 'default': { 'ENGINE': 'django_db_geventpool.backends.postgresql', 'HOST': 'localhost', 'PORT': '5432', 'NAME': 'mydb', 'USER': 'myuser', 'PASSWORD': 'mypassword', 'OPTIONS': { 'MAX_CONNS': 20, 'REUSE_CONNS': 10 } } } -
分表策略:
对于超大型表,可以使用django-postgres-extra的分表功能:python复制from postgres_extra.models import PostgresPartitionedModel class LogEntry(PostgresPartitionedModel): class PartitioningMeta: method = PostgresPartitionedModel.RANGE key = ["timestamp"] timestamp = models.DateTimeField() message = models.TextField()
10.2 缓存策略深度优化
Django支持多级缓存,我的典型配置如下:
-
视图级缓存:
python复制from django.views.decorators.cache import cache_page @cache_page(60 * 15) # 15分钟缓存 def my_view(request): ... -
模板片段缓存:
html复制{% load cache %} {% cache 500 sidebar %} <!-- 侧边栏内容 --> {% endcache %} -
低级API缓存:
python复制from django.core.cache import caches def get_expensive_data(): cache = caches['alternate'] data = cache.get('expensive_data') if not data: data = calculate_expensive_data() cache.set('expensive_data', data, timeout=3600) return data -
Redis缓存后端配置:
python复制CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", "PASSWORD": "yourpassword", "SOCKET_CONNECT_TIMEOUT": 5, "SOCKET_TIMEOUT": 5, } } }
在特别高并发的场景下,我还实现了缓存预热和防雪崩策略:
python复制import threading
class CacheWarmer:
_lock = threading.Lock()
@classmethod
def warm_cache(cls, key, func, timeout):
with cls._lock:
cache = caches['default']
if not cache.get(key):
data = func()
cache.set(key, data, timeout)
return data
return cache.get(key)
11. Django国际化与本地化
11.1 多语言支持实现
Django内置了强大的国际化(i18n)系统。实现多语言网站的步骤如下:
-
配置设置:
python复制# settings.py LANGUAGE_CODE = 'en-us' TIME_ZONE = 'UTC' USE_I18N = True USE_L10N = True USE_TZ = True LANGUAGES = [ ('en', 'English'), ('zh-hans', 'Simplified Chinese'), ('ja', 'Japanese'), ] LOCALE_PATHS = [ os.path.join(BASE_DIR, 'locale'), ] -
标记翻译字符串:
python复制from django.utils.translation import gettext as _ output = _("Welcome to my site.") # 带变量的翻译 count = 5 output = _("You have %(count)d messages") % {'count': count} -
模板中的翻译:
html复制{% load i18n %} <title>{% trans "My Title" %}</title> <p>{% blocktrans count counter=images|length %} Here is a single image. {% plural %} Here are {{ counter }} images. {% endblocktrans %}</p> -
生成翻译文件:
bash复制
django-admin makemessages -l zh_Hans django-admin makemessages -l ja -
编译翻译:
bash复制
django-admin compilemessages
11.2 本地化最佳实践
在实际项目中,我总结了以下本地化经验:
-
日期时间处理:
python复制from django.utils import timezone from django.utils.formats import date_format now = timezone.now() local_date = date_format(now, format='SHORT_DATE_FORMAT', use_l10n=True) -
货币格式化:
python复制from django.utils.formats import number_format price = 1234.56 localized_price = number_format(price, decimal_pos=2, use_l10n=True) -
语言切换中间件:
python复制class LocaleMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): language = self.get_language_from_request(request) translation.activate(language) request.LANGUAGE_CODE = language response = self.get_response(request) return response -
内容翻译模型:
对于需要用户生成内容的翻译,我通常使用django-modeltranslation:python复制from modeltranslation.translator import register, TranslationOptions from .models import Product @register(Product) class ProductTranslationOptions(TranslationOptions): fields = ('name', 'description',)
12. Django异步任务处理
12.1 Celery集成实践
对于耗时任务,我通常使用Celery进行异步处理:
-
基础配置:
python复制# settings.py CELERY_BROKER_URL = 'redis://localhost:6379/0' CELERY_RESULT_BACKEND = 'redis://localhost:6379/1' CELERY_TIMEZONE = TIME_ZONE -
任务定义:
python复制# tasks.py from celery import shared_task from django.core.mail import send_mail @shared_task(bind=True) def send_notification_email(self, user_id): try: user = User.objects.get(id=user_id) send_mail( 'Your Notification', 'Here is your message.', 'from@example.com', [user.email], fail_silently=False, ) except Exception as exc: self.retry(exc=exc, countdown=60) -
任务调用:
python复制send_notification_email.delay(user.id)
12.2 异步视图支持
Django 3.1+原生支持异步视图:
python复制from django.http import HttpResponse
from asgiref.sync import sync_to_async
from .models import Post
async def post_list(request):
posts = await sync_to_async(list)(Post.objects.all())
return HttpResponse("\n".join(post.title for post in posts))
对于数据库操作,需要注意:
- ORM大部分操作不是原生异步的
- 需要使用
sync_to_async适配器 - 第三方库可能有异步支持问题
我在实际项目中发现,混合使用同步和异步代码时容易出现死锁,特别是在使用sync_to_async时。解决方案是配置不同的线程池:
python复制from asgiref.sync import sync_to_async
database_sync_to_async = sync_to_async(
thread_sensitive=True,
executor=ThreadPoolExecutor(max_workers=1)
)
other_sync_to_async = sync_to_async(
thread_sensitive=False,
executor=ThreadPoolExecutor(max_workers=10)
)
13. Django与微服务架构
13.1 服务拆分策略
将单体Django应用拆分为微服务时,我通常遵循以下步骤:
-
识别边界上下文:
- 用户服务(认证、权限)
- 内容服务(博客、CMS)
- 电商服务(产品、订单)
- 支付服务
-
通信方式选择:
- REST API:简单直接
- gRPC:高性能场景
- 消息队列:事件驱动架构
-
数据一致性处理:
- 分布式事务(Saga模式)
- 最终一致性
- 事件溯源
13.2 服务间认证方案
微服务间通信的安全至关重要,我常用的方案包括:
-
JWT认证:
python复制# settings.py REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], } -
服务间认证:
python复制class ServiceAuthMiddleware: def __init__(self, get_response): self.get_response = get_response def __call__(self, request): service_token = request.headers.get('X-Service-Token') if not validate_service_token(service_token): return HttpResponseForbidden() return self.get_response(request) -
API网关集成:
使用Kong或Apigee等网关统一处理认证和路由。
14. Django项目监控与日志
14.1 日志配置最佳实践
合理的日志配置能极大简化问题排查:
python复制# settings.py
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'formatters': {
'verbose': {
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
'style': '{',
},
'simple': {
'format': '{levelname} {message}',
'style': '{',
},
},
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/django/debug.log',
'formatter': 'verbose'
},
'console': {
'level': 'INFO',
'class': 'logging.StreamHandler',
'formatter': 'simple'
},
},
'loggers': {
'django': {
'handlers': ['file', 'console'],
'level': 'INFO',
'propagate': True,
},
'myapp': {
'handlers': ['file', 'console'],
'level': 'DEBUG',
'propagate': False,
},
},
}
14.2 性能监控集成
我常用的监控方案组合:
-
应用性能监控(APM):
- Elastic APM
- New Relic
- Datadog
-
错误跟踪:
- Sentry
- Rollbar
-
指标监控:
- Prometheus + Grafana
- StatsD + Graphite
Elastic APM的集成示例:
python复制# settings.py
INSTALLED_APPS += ('elasticapm.contrib.django',)
ELASTIC_APM = {
'SERVICE_NAME': 'my-django-app',
'SECRET_TOKEN': 'your_token',
'SERVER_URL': 'http://apm-server:8200',
}
MIDDLEWARE = [
'elasticapm.contrib.django.middleware.TracingMiddleware',
...
]
15. Django项目持续集成与部署
15.1 CI/CD流水线设计
我的典型Django CI/CD流程包括:
-
代码质量检查:
- flake8/Pylint静态分析
- Bandit安全扫描
- 单元测试覆盖率
-
自动化测试:
yaml复制# .github/workflows/test.yml name: Django CI on: [push, pull_request] jobs: test: runs-on: ubuntu-latest services: postgres: image: postgres:13 env: POSTGRES_PASSWORD: postgres ports: - 5432:5432 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.9' - name: Install dependencies run: | python -m pip install --upgrade pip pip install -r requirements.txt - name: Run tests env: DATABASE_URL: postgres://postgres:postgres@localhost:5432/postgres run: | python manage.py test -
部署策略:
- 蓝绿部署
- 金丝雀发布
- 滚动更新
15.2 Docker化部署
我的标准Django Dockerfile:
dockerfile复制# Dockerfile
FROM python:3.9-slim
ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1 \
PIP_NO_CACHE_DIR=1
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
RUN python manage.py collectstatic --noinput
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi"]
对应的docker-compose.yml:
yaml复制version: '3.8'
services:
web:
build: .
ports:
- "8000:8000"
environment:
- DATABASE_URL=postgres://postgres:password@db:5432/app
depends_on:
- db
- redis
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: password
POSTGRES_DB: app
volumes:
- postgres_data:/var/lib/postgresql/data
redis:
image: redis:6
celery:
build: .
command: celery -A config worker -l info
depends_on:
- redis
celery-beat:
build: .
command: celery -A config beat -l info
depends_on:
- redis
volumes:
postgres_data:
16. Django项目安全加固
16.1 常见漏洞防护
-
SQL注入:
- 始终使用ORM或参数化查询
- 避免直接拼接SQL
-
XSS攻击:
- 模板自动转义
- 谨慎使用
mark_safe - 设置Content Security Policy(CSP)
-
CSRF防护:
- 确保所有修改操作使用POST
- 表单包含
{% csrf_token %} - 配置CSRF_TRUSTED_ORIGINS
-
文件上传安全:
- 验证文件类型和内容
- 限制文件大小
- 存储到非Web可访问目录
16.2 安全头设置
推荐的安全中间件配置:
python复制# settings.py
SECURE_BROWSER_XSS_FILTER = True
SECURE_CONTENT_TYPE_NOSNIFF = True
X_FRAME_OPTIONS = 'DENY'
SECURE_REFERRER_POLICY = 'same-origin'
SECURE_HSTS_SECONDS = 31536000 # 1 year
SECURE_HSTS_INCLUDE_SUBDOMAINS = True
SECURE_HSTS_PRELOAD = True
# 对于HTTPS站点
SESSION_COOKIE_SECURE = True
CSRF_COOKIE_SECURE = True
SECURE_SSL_REDIRECT = True
17. Django项目调试技巧
17.1 开发环境调试
-
Django Debug Toolbar:
python复制# settings.py if DEBUG: INSTALLED_APPS += ['debug_toolbar'] MIDDLEWARE.insert(0, 'debug_toolbar.middleware.DebugToolbarMiddleware') INTERNAL_IPS = ['127.0.0.1'] -
IPython集成:
python复制# manage.py from IPython import embed def shell_plus(): import django django.setup() embed() -
Django Extensions:
bash复制
python manage.py shell_plus --ipython python manage.py runserver_plus --cert-file cert.crt
17.2 生产环境调试
- Sentry集成:
python复制# settings.py import sentry_sdk from sentry_sdk.integrations.django
