1. Django框架概述:为什么选择它?
Django是一个基于Python的高级Web框架,它遵循"不重复造轮子"(Don't Repeat Yourself)的理念。我第一次接触Django是在2013年为一个新闻门户网站做后端开发,当时就被它"开箱即用"的特性所震撼。与其他框架相比,Django最显著的特点是自带完整的开发工具链——从ORM到admin后台,从模板引擎到表单处理,几乎覆盖了Web开发的所有基础需求。
Django的核心优势在于:
- 全栈式框架:不像Flask那样需要自己组装各种组件,Django已经为你准备好了从数据库操作到前端模板的一整套工具
- 安全防护内置:自动处理SQL注入、XSS、CSRF等常见Web安全问题
- 可扩展架构:虽然功能齐全,但每个模块都可以被替换或扩展
- 文档质量极高:官方文档被公认为Python生态中最完善的框架文档之一
提示:如果你正在犹豫选择Django还是Flask,简单判断标准是——需要快速开发完整应用选Django,需要极简微服务选Flask。
2. Django项目典型结构解析
一个标准的Django项目(使用django-admin startproject创建)会生成如下结构:
code复制myproject/
├── manage.py # 项目管理脚本
├── myproject/
│ ├── __init__.py
│ ├── settings.py # 所有配置项
│ ├── urls.py # 主路由配置
│ └── wsgi.py # WSGI入口
└── requirements.txt # 依赖文件(需手动创建)
但实际开发中,我推荐使用改进后的结构(这是我经过20+个项目总结的最佳实践):
code复制project/
├── apps/ # 所有应用模块
│ ├── users/ # 用户系统
│ └── products/ # 商品模块
├── config/ # 原myproject目录
│ ├── settings/
│ │ ├── base.py # 基础配置
│ │ ├── dev.py # 开发环境
│ │ └── prod.py # 生产环境
│ └── urls.py
├── static/ # 静态文件
├── templates/ # 全局模板
└── manage.py
这种结构的优势在于:
- 应用模块化程度更高
- 环境配置分离更清晰
- 静态资源管理更方便
3. Django ORM深度使用技巧
Django的ORM是其最强大的功能之一。以下是我总结的几个高级技巧:
3.1 查询优化方案
python复制# 反例(N+1查询问题)
books = Book.objects.all()
for book in books:
print(book.author.name) # 每次循环都查询数据库
# 正例(使用select_related)
books = Book.objects.select_related('author').all()
对于多对多关系,应该使用prefetch_related:
python复制# 预取所有相关对象
stores = Store.objects.prefetch_related('books').all()
3.2 自定义Manager
在models.py中添加自定义查询方法:
python复制class PublishedBookManager(models.Manager):
def get_queryset(self):
return super().get_queryset().filter(status='published')
class Book(models.Model):
objects = models.Manager() # 默认manager
published = PublishedBookManager() # 自定义manager
使用时:
python复制Book.published.all() # 只获取已发布的书籍
3.3 批量操作
避免使用循环+save(),改用bulk操作:
python复制# 低效方式
for book in Book.objects.filter(price__lt=10):
book.price += 1
book.save()
# 高效方式
Book.objects.filter(price__lt=10).update(price=F('price')+1)
4. Django Admin高级定制
Django Admin不只是简单的后台,通过定制可以实现强大功能:
4.1 自定义显示字段
python复制@admin.register(Book)
class BookAdmin(admin.ModelAdmin):
list_display = ('title', 'author', 'price', 'publish_date')
list_filter = ('author', 'publish_date')
search_fields = ('title', 'author__name')
4.2 添加自定义操作
python复制def make_expensive(modeladmin, request, queryset):
queryset.update(price=F('price')*1.2)
make_expensive.short_description = "涨价20%"
class BookAdmin(admin.ModelAdmin):
actions = [make_expensive]
4.3 集成富文本编辑器
安装django-ckeditor:
bash复制pip install django-ckeditor
配置settings.py:
python复制INSTALLED_APPS += ('ckeditor',)
模型中使用:
python复制from ckeditor.fields import RichTextField
class Post(models.Model):
content = RichTextField()
5. Django项目部署实战
5.1 生产环境配置要点
修改config/settings/prod.py:
python复制DEBUG = False
ALLOWED_HOSTS = ['yourdomain.com']
STATIC_ROOT = '/var/www/static/'
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'mydb',
'USER': 'dbuser',
'PASSWORD': 'complexpassword',
'HOST': 'localhost',
'PORT': '5432',
}
}
5.2 使用Gunicorn+Nginx
安装Gunicorn:
bash复制pip install gunicorn
启动命令:
bash复制gunicorn --workers 3 --bind unix:/tmp/gunicorn.sock config.wsgi
Nginx配置示例:
nginx复制server {
listen 80;
server_name yourdomain.com;
location /static/ {
alias /var/www/static/;
}
location / {
proxy_pass http://unix:/tmp/gunicorn.sock;
proxy_set_header Host $host;
}
}
5.3 使用Docker部署
Dockerfile示例:
dockerfile复制FROM python:3.9
WORKDIR /app
COPY requirements.txt .
RUN pip install -r requirements.txt
COPY . .
CMD ["gunicorn", "--bind", "0.0.0.0:8000", "config.wsgi"]
docker-compose.yml:
yaml复制version: '3'
services:
web:
build: .
ports:
- "8000:8000"
volumes:
- .:/app
depends_on:
- db
db:
image: postgres:13
environment:
POSTGRES_PASSWORD: complexpassword
6. 常见问题排查指南
6.1 静态文件404错误
可能原因及解决方案:
- DEBUG=False时未配置STATIC_ROOT
- Nginx/Apache未正确配置静态文件路径
- 未运行
collectstatic命令
6.2 数据库连接问题
PostgreSQL常见错误排查:
bash复制# 检查服务状态
sudo systemctl status postgresql
# 检查连接权限
psql -U postgres -c "SELECT usename,client_addr FROM pg_stat_activity;"
6.3 性能优化检查点
使用django-debug-toolbar分析:
- 安装:
pip install django-debug-toolbar - 配置settings.py:
python复制INSTALLED_APPS += ['debug_toolbar']
MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware']
INTERNAL_IPS = ['127.0.0.1']
- 检查重复查询、慢查询
7. 项目实战经验分享
7.1 用户系统设计要点
推荐使用django-allauth:
python复制# settings.py
INSTALLED_APPS = [
...,
'allauth',
'allauth.account',
'allauth.socialaccount',
]
AUTHENTICATION_BACKENDS = (
'django.contrib.auth.backends.ModelBackend',
'allauth.account.auth_backends.AuthenticationBackend',
)
7.2 异步任务处理
使用Celery的最佳实践:
- 安装:
pip install celery redis - 创建config/celery.py:
python复制import os
from celery import Celery
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'config.settings')
app = Celery('config')
app.config_from_object('django.conf:settings', namespace='CELERY')
app.autodiscover_tasks()
- 在__init__.py中添加:
python复制from .celery import app as celery_app
__all__ = ('celery_app',)
7.3 API开发建议
使用DRF(Django REST Framework)的要点:
python复制# serializers.py
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = '__all__'
extra_kwargs = {'price': {'min_value': 0}}
# views.py
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [filters.SearchFilter]
search_fields = ['title', 'author__name']
8. 开发工具链推荐
8.1 VS Code配置
推荐安装的扩展:
- Python
- Django
- SQLTools
- REST Client
settings.json配置:
json复制{
"python.linting.pylintEnabled": true,
"python.formatting.provider": "black",
"emmet.includeLanguages": {
"django-html": "html"
}
}
8.2 测试工具选择
必备测试组合:
python复制# tests.py
from django.test import TestCase, Client
from django.urls import reverse
class BookTests(TestCase):
def setUp(self):
self.client = Client()
self.book = Book.objects.create(title="Test Book", price=10)
def test_book_listing(self):
response = self.client.get(reverse('book-list'))
self.assertEqual(response.status_code, 200)
self.assertContains(response, "Test Book")
8.3 监控与日志
推荐使用Sentry进行错误监控:
- 安装:
pip install sentry-sdk - 配置settings.py:
python复制import sentry_sdk
sentry_sdk.init(
dsn="your-dsn",
integrations=[DjangoIntegration()],
traces_sample_rate=1.0,
)
日志配置示例:
python复制LOGGING = {
'version': 1,
'handlers': {
'file': {
'level': 'DEBUG',
'class': 'logging.FileHandler',
'filename': '/var/log/django/debug.log',
},
},
'loggers': {
'django': {
'handlers': ['file'],
'level': 'DEBUG',
},
},
}
经过多年Django开发实践,我认为最关键的是要深入理解其"约定优于配置"的哲学。刚开始可能会觉得框架限制多,但当你熟悉这些约定后,开发效率会成倍提升。特别是在团队协作中,统一的框架约定能极大降低沟通成本。
