1. Django入门:为什么选择这个框架?
第一次接触Django是在2013年,当时我需要快速开发一个内容管理系统。相比其他Python框架,Django最吸引我的是它的"全栈"特性——开箱即用的Admin后台、ORM系统、模板引擎和认证模块,这些组件已经紧密集成,不需要额外拼凑。
Django采用MTV(Model-Template-View)模式,这与传统的MVC略有不同:
- Model:定义数据结构,直接映射到数据库表
- Template:负责前端展示层
- View:处理业务逻辑,连接Model和Template
新手常见误区:很多人会把Django的View等同于MVC的Controller,实际上Django的View更接近MVC中的View逻辑部分,而URL配置部分承担了部分Controller的职责。
2. 开发环境搭建与第一个项目
2.1 Python环境配置
建议使用Python 3.8+版本,这是目前大多数云平台兼容性最好的版本。我习惯用pyenv管理多版本Python:
# 安装pyenv(Mac) brew install pyenv # 安装指定Python版本 pyenv install 3.8.12 # 创建虚拟环境 python -m venv myenv source myenv/bin/activate2.2 Django安装与项目创建
pip install django==4.2 # 使用LTS版本 django-admin startproject mysite生成的项目结构包含:
- manage.py:项目管理脚本
- mysite/settings.py:全局配置
- mysite/urls.py:URL路由入口
- mysite/wsgi.py:WSGI应用入口
实用技巧:在settings.py中立即修改ALLOWED_HOSTS = ['*'],方便本地测试,上线前务必修正。
3. 核心组件深度解析
3.1 模型(Model)与ORM
Django的ORM让我告别了手写SQL。定义一个博客文章模型:
from django.db import models class Article(models.Model): title = models.CharField(max_length=200) content = models.TextField() pub_date = models.DateTimeField(auto_now_add=True) author = models.ForeignKey('auth.User', on_delete=models.CASCADE) def __str__(self): return self.title执行数据库迁移:
python manage.py makemigrations python manage.py migrateORM查询示例:
# 获取所有文章 articles = Article.objects.all() # 条件查询 recent_articles = Article.objects.filter( pub_date__gte=timezone.now()-timedelta(days=7) ).order_by('-pub_date')3.2 视图(View)的三种实现方式
- 函数视图(适合简单逻辑)
from django.http import HttpResponse def article_list(request): articles = Article.objects.all() output = ', '.join([a.title for a in articles]) return HttpResponse(output)- 类视图(推荐方式)
from django.views.generic import ListView class ArticleListView(ListView): model = Article template_name = 'article_list.html' context_object_name = 'articles'- DRF视图(API开发)
from rest_framework import generics class ArticleAPIView(generics.ListAPIView): queryset = Article.objects.all() serializer_class = ArticleSerializer4. 模板系统实战技巧
4.1 基础模板继承
创建base.html:
<!DOCTYPE html> <html> <head> <title>{% block title %}默认标题{% endblock %}</title> </head> <body> {% block content %}{% endblock %} </body> </html>子模板扩展:
{% extends "base.html" %} {% block title %}文章列表{% endblock %} {% block content %} <ul> {% for article in articles %} <li>{{ article.title }}</li> {% endfor %} </ul> {% endblock %}4.2 自定义模板标签
当内置标签不够用时,可以创建自定义标签。在app目录下创建templatetags/my_tags.py:
from django import template register = template.Library() @register.simple_tag def recent_articles(count=5): return Article.objects.order_by('-pub_date')[:count]模板中使用:
{% load my_tags %} {% recent_articles 3 as recent_list %}5. Django Admin深度定制
默认Admin后台已经很强大了,但通过定制可以更高效:
from django.contrib import admin @admin.register(Article) class ArticleAdmin(admin.ModelAdmin): list_display = ('title', 'author', 'pub_date') list_filter = ('pub_date', 'author') search_fields = ('title', 'content') prepopulated_fields = {'slug': ('title',)} fieldsets = ( (None, { 'fields': ('title', 'slug', 'author', 'content') }), ('高级选项', { 'fields': ('pub_date',), 'classes': ('collapse',) }), )生产环境安全提示:务必修改Admin后台URL路径,避免使用默认的/admin/。
6. 项目部署实战
6.1 宝塔面板部署
- 安装Python项目管理器
- 添加项目,选择Python版本
- 配置项目路径和启动命令:
/www/wwwroot/mysite/venv/bin/gunicorn --bind 127.0.0.1:8000 mysite.wsgi:application - 设置静态文件映射
6.2 性能优化配置
settings.py关键配置:
# 生产环境务必设置 DEBUG = False # 静态文件配置 STATIC_ROOT = os.path.join(BASE_DIR, 'static') # 数据库连接池 DATABASES = { 'default': { 'ENGINE': 'django.db.backends.postgresql', 'CONN_MAX_AGE': 600, # 连接池保持时间 } } # 缓存配置 CACHES = { "default": { "BACKEND": "django.core.cache.backends.redis.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", } }7. 开发中的高频问题解决方案
7.1 跨域问题处理
安装django-cors-headers:
pip install django-cors-headers配置settings.py:
INSTALLED_APPS = [ ..., 'corsheaders', ] MIDDLEWARE = [ 'corsheaders.middleware.CorsMiddleware', ..., ] CORS_ALLOW_ALL_ORIGINS = True # 开发时使用,生产环境应指定域名7.2 静态文件404问题
开发环境需要配置URL:
from django.conf import settings from django.conf.urls.static import static urlpatterns = [ ..., ] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)生产环境需要收集静态文件:
python manage.py collectstatic7.3 ORM性能优化
- 使用select_related减少查询:
# 优化前:N+1查询问题 articles = Article.objects.all() for a in articles: print(a.author.username) # 每次循环都查询author # 优化后 articles = Article.objects.select_related('author').all()- 使用prefetch_related优化多对多关系:
articles = Article.objects.prefetch_related('tags').all()- 使用values()/values_list()获取特定字段:
titles = Article.objects.values_list('title', flat=True)8. 项目结构优化建议
经过多个项目实践,我总结出这样的结构:
myproject/ ├── apps/ # 所有应用模块 │ ├── blog/ # 博客应用 │ └── users/ # 用户管理 ├── config/ # 项目配置 │ ├── settings/ # 多环境配置 │ │ ├── base.py │ │ ├── dev.py │ │ └── prod.py │ └── urls.py # 主路由 ├── static/ # 静态文件 ├── templates/ # 全局模板 └── manage.py关键配置技巧:
- 拆分settings.py为多环境配置
- 使用环境变量管理敏感信息(推荐python-dotenv)
- 自定义用户模型(项目开始时就做)
# settings/base.py AUTH_USER_MODEL = 'users.CustomUser'9. 测试驱动开发实践
9.1 模型测试
from django.test import TestCase from .models import Article class ArticleModelTest(TestCase): @classmethod def setUpTestData(cls): Article.objects.create(title='Test Title', content='Test Content') def test_title_content(self): article = Article.objects.get(id=1) self.assertEqual(article.title, 'Test Title') self.assertTrue('Content' in article.content)9.2 视图测试
from django.urls import reverse class ArticleViewTest(TestCase): def test_view_url_exists(self): response = self.client.get('/articles/') self.assertEqual(response.status_code, 200) def test_view_uses_correct_template(self): response = self.client.get(reverse('article-list')) self.assertTemplateUsed(response, 'blog/article_list.html')9.3 API测试(使用DRF)
from rest_framework.test import APITestCase class ArticleAPITest(APITestCase): def test_api_list_view(self): response = self.client.get(reverse('api-article-list')) self.assertEqual(response.status_code, 200) self.assertEqual(len(response.data), 0) # 初始无数据10. 进阶学习路线
掌握基础后,建议按这个顺序深入:
- Django REST Framework(API开发)
- Django Channels(WebSocket支持)
- Celery + Django(异步任务)
- Django与微服务架构
- Django安全深度实践
推荐的学习资源:
- 官方文档(永远是最好的参考)
- 《Django for Professionals》系列
- DjangoCon会议视频
- 源码阅读(特别是中间件和请求响应周期部分)