1. Django框架核心架构解析
作为Python生态中最成熟的Web框架,Django采用经典的MTV模式(Model-Template-View),这与传统的MVC模式有着微妙的差异。模型层(Model)负责数据定义与数据库交互,通过ORM将Python类映射为SQL表结构。一个典型的模型定义如下:
python复制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)
def __str__(self):
return self.title
模板层(Template)使用Django特有的模板语言(DTL),支持模板继承和变量渲染。基础模板通常包含区块(block)定义:
html复制<!-- base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
视图层(View)作为业务逻辑的核心,既可以是函数视图也可以是类视图。以下是基于类的通用视图示例:
python复制from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'article_list.html'
context_object_name = 'articles'
paginate_by = 10
关键经验:在模型字段选择时,CharField适合短文本,TextField用于大段内容。auto_now_add会在对象创建时自动设置时间,而auto_now会在每次保存时更新时间。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. URL路由配置详解
Django的URL分发系统通过urls.py文件配置,支持正则表达式和路径转换器。项目根URL配置通常包含各个应用的URL包含:
python复制# project/urls.py
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('blog/', include('blog.urls')),
]
应用级URL配置可以定义命名路由和参数捕获:
python复制# blog/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.ArticleListView.as_view(), name='article-list'),
path('<int:pk>/', views.ArticleDetailView.as_view(), name='article-detail'),
path('category/<slug:slug>/', views.category_view, name='category-filter'),
]
路径转换器类型包括:
- str:匹配非空字符串(默认)
- int:匹配正整数
- slug:匹配字母、数字、连字符和下划线
- uuid:匹配UUID字符串
- path:匹配包含斜线的字符串
路由陷阱:避免在路径末尾添加斜杠(除非必要),因为APPEND_SLASH设置可能导致重复重定向。命名路由(name参数)在模板中使用{% url %}标签时至关重要。
3. 模板系统深度应用
Django模板语言(DTL)虽然简单但功能强大。模板继承通过三层结构实现:
- 基础模板(base.html)定义可替换区块
- 子模板使用{% extends %}继承并覆盖区块
- 包含模板片段使用
变量过滤器的链式调用:
html复制{{ article.pub_date|date:"Y-m-d"|lower }}
常用过滤器:
- length:获取列表长度
- slice:列表切片
- truncatechars:截断字符
- safe:标记HTML安全
- floatformat:浮点数格式化
模板标签的进阶用法:
html复制{% with total=products|length %}
{{ total }} product{{ total|pluralize }}
{% endwith %}
{% for item in list %}
{% cycle 'row1' 'row2' as rowcolors %}
{% empty %}
<p>暂无数据</p>
{% endfor %}
性能提示:过度使用include可能导致模板渲染性能下降。对于频繁使用的UI组件,考虑使用自定义模板标签替代。
4. 表单处理与验证机制
Django表单系统自动处理CSRF防护、数据验证和HTML生成。模型表单(ModelForm)能自动根据模型生成表单:
python复制from django import forms
from .models import Comment
class CommentForm(forms.ModelForm):
class Meta:
model = Comment
fields = ['name', 'email', 'content']
widgets = {
'content': forms.Textarea(attrs={'rows': 4}),
}
表单视图处理POST请求的标准流程:
python复制def comment_create(request, article_id):
article = get_object_or_404(Article, pk=article_id)
if request.method == 'POST':
form = CommentForm(request.POST)
if form.is_valid():
comment = form.save(commit=False)
comment.article = article
comment.save()
return redirect(article)
else:
form = CommentForm()
return render(request, 'comment_form.html', {'form': form})
表单验证的三种方式:
- 字段级验证:clean_
方法 - 表单级验证:clean方法
- 模型级验证:重写save方法或使用信号
安全实践:永远使用CSRF中间件,对文件上传要配置MEDIA_ROOT和MEDIA_URL,并使用FileField的upload_to参数指定存储路径。
5. 数据库查询优化技巧
Django ORM提供了强大的查询API,但需要避免常见的性能陷阱。select_related用于外键关系的立即加载:
python复制# 单个SQL查询获取文章及作者
articles = Article.objects.select_related('author').all()
prefetch_related适用于多对多关系:
python复制# 两个SQL查询优化多对多获取
articles = Article.objects.prefetch_related('tags').all()
查询集的惰性特性意味着以下代码只执行一次数据库查询:
python复制queryset = Article.objects.filter(status='published')
print(queryset) # 执行查询
print(queryset) # 使用缓存
常用查询表达式:
- F():引用字段值
- Q():复杂条件组合
- Count/Sum/Avg:聚合函数
- Subquery:子查询
python复制from django.db.models import F, Q
Article.objects.filter(
Q(pub_date__year=2023) | Q(views__gt=F('comments'))
).update(status='featured')
调试技巧:使用connection.queries查看实际执行的SQL语句,或在settings.py中配置LOGGING记录慢查询。
6. 用户认证系统集成
Django内置的auth应用提供完整的认证解决方案。用户模型扩展推荐方式:
python复制from django.contrib.auth.models import AbstractUser
class CustomUser(AbstractUser):
bio = models.TextField(blank=True)
avatar = models.ImageField(upload_to='avatars/', blank=True)
在settings.py中指定自定义用户模型:
python复制AUTH_USER_MODEL = 'accounts.CustomUser'
登录视图的典型实现:
python复制from django.contrib.auth import authenticate, login
def my_login(request):
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(request, username=username, password=password)
if user is not None:
login(request, user)
return redirect('home')
return render(request, 'login.html')
权限控制装饰器:
- @login_required:要求登录
- @permission_required:检查特定权限
- @user_passes_test:自定义权限检查
安全警示:密码必须使用make_password存储,永远不要直接存储明文密码。Session配置应考虑设置SESSION_COOKIE_AGE和SESSION_SAVE_EVERY_REQUEST。
7. 静态文件管理与部署
Django的静态文件系统通过STATIC_URL和STATIC_ROOT配置。开发阶段使用:
python复制STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'static']
生产环境需要收集静态文件:
bash复制python manage.py collectstatic
文件上传配置示例:
python复制MEDIA_URL = '/media/'
MEDIA_ROOT = BASE_DIR / 'media'
URL配置需要添加静态文件服务(仅开发用):
python复制from django.conf import settings
from django.conf.urls.static import static
urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
WhiteNoise中间件优化静态文件服务:
python复制MIDDLEWARE = [
# ...
'whitenoise.middleware.WhiteNoiseMiddleware',
]
STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage'
部署要点:生产环境应使用Nginx/Apache处理静态文件,DEBUG必须设置为False,ALLOWED_HOSTS要明确指定域名。
8. 测试驱动开发实践
Django测试框架继承自Python的unittest。模型测试示例:
python复制from django.test import TestCase
from .models import Article
class ArticleModelTest(TestCase):
@classmethod
def setUpTestData(cls):
Article.objects.create(title='Test', content='Content')
def test_title_content(self):
article = Article.objects.get(id=1)
self.assertEqual(article.title, 'Test')
self.assertEqual(article.content, 'Content')
视图测试常用方法:
python复制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, 'article_list.html')
测试客户端模拟用户操作:
python复制def test_login(self):
response = self.client.login(username='test', password='secret')
self.assertTrue(response)
工厂模式创建测试数据:
python复制from factory.django import DjangoModelFactory
class ArticleFactory(DjangoModelFactory):
class Meta:
model = Article
title = 'Factory Article'
content = 'Factory Content'
测试策略:单元测试应覆盖核心业务逻辑,集成测试验证组件交互,端到端测试模拟用户旅程。测试数据库与生产环境隔离,每次测试后自动回滚。
