1. Django模板语法:从入门到实战
Django的模板系统是连接后端逻辑与前端展示的核心桥梁。作为一个全栈开发者,掌握模板语法不仅能提升开发效率,更能实现前后端的优雅解耦。我在多个电商项目中验证过,合理使用模板继承和自定义标签可以减少60%以上的重复前端代码。
1.1 基础变量输出与过滤器
Django模板中最基础的{{ variable }}语法看似简单,但实际开发中容易踩坑。比如当变量值为None时,默认Django会显示空字符串而非报错,这与Python的常规行为不同。我建议始终使用默认值过滤器:
django复制{{ user.balance|default:"0.00" }}
常用过滤器还有:
date:日期格式化(需配合settings.py的TIME_ZONE配置)slice:列表切片(比Python的切片语法更安全)safe:标记HTML内容为安全(慎用!需配合XSS防护)
重要提示:永远不要直接渲染用户输入的
safe内容,我在实际项目中见过因此导致的XSS攻击案例。
1.2 逻辑控制标签详解
{% if %}标签支持嵌套和复杂逻辑,但要注意它使用的是Python的短路求值:
django复制{% if products and products.0.price > 100 %}
高价商品区
{% elif not products %}
商品列表为空
{% endif %}
{% for %}循环有几个特别有用的内置变量:
forloop.counter:当前循环次数(从1开始)forloop.revcounter:剩余循环次数forloop.first/last:首尾项判断
1.3 模板继承与组件化
这是Django模板最强大的特性。基础模板(base.html)通常包含:
django复制<!DOCTYPE html>
<html>
<head>
<title>{% block title %}默认标题{% endblock %}</title>
{% block extra_head %}{% endblock %}
</head>
<body>
{% include "_navbar.html" %}
<div class="content">
{% block content %}{% endblock %}
</div>
{% include "_footer.html" %}
</body>
</html>
子模板通过{% extends %}继承后,可以覆盖任意block。我习惯在大型项目中建立这样的目录结构:
code复制templates/
├── base/
│ ├── base.html
│ ├── _navbar.html
│ └── _footer.html
├── products/
│ └── list.html
└── users/
└── profile.html
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 请求处理:从URL到视图
2.1 URL路由设计规范
urls.py是Django应用的入口。我推荐使用path()代替传统的url(),它更直观且支持类型转换:
python复制# 旧式(兼容但已不推荐)
url(r'^articles/(?P<year>[0-9]{4})/$', views.year_archive)
# 新式(Django 2.0+)
path('articles/<int:year>/', views.year_archive)
对于大型项目,建议采用分路由策略:
python复制# 主urls.py
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
path('', include('frontend.urls')),
]
# api/urls.py
urlpatterns = [
path('users/', user_views.list),
path('products/', product_views.list),
]
2.2 请求对象深度解析
HttpRequest对象包含的常用属性:
| 属性 | 类型 | 说明 |
|---|---|---|
| method | str | GET/POST等 |
| GET | QueryDict | URL参数 |
| POST | QueryDict | 表单数据 |
| FILES | MultiValueDict | 上传文件 |
| user | User | 认证用户 |
| session | dict | 会话数据 |
处理表单时常见的坑:
- POST请求必须带
{% csrf_token %} - 文件上传需要设置
enctype="multipart/form-data" - 获取多选值要用
request.POST.getlist()
2.3 类视图最佳实践
相比函数视图,类视图更适合复杂场景。这是我常用的模板:
python复制from django.views.generic import ListView
from django.contrib.auth.mixins import LoginRequiredMixin
class ProductListView(LoginRequiredMixin, ListView):
model = Product
template_name = 'products/list.html'
paginate_by = 20
context_object_name = 'products'
def get_queryset(self):
# 添加业务逻辑
return super().get_queryset().filter(
is_active=True
).select_related('category')
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['now'] = timezone.now()
return context
3. 响应生成与优化技巧
3.1 HttpResponse的多种形态
基础响应:
python复制return HttpResponse("文本内容", content_type="text/plain")
常见快捷响应:
python复制from django.shortcuts import render, redirect
def view_func(request):
if not request.user.is_authenticated:
return redirect('/login/')
return render(request, 'template.html', {'data': data})
JSON响应(DRF出现前):
python复制from django.http import JsonResponse
def api_view(request):
data = {'code': 200, 'data': [...]}
return JsonResponse(data)
3.2 静态文件处理要点
开发环境配置:
python复制# settings.py
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / "static"]
# 模板中使用
{% load static %}
<img src="{% static 'images/logo.png' %}">
生产环境必须:
- 运行
collectstatic命令 - 配置Nginx/Apache处理静态文件
- 启用WhiteNoise中间件(Python方案)
3.3 性能优化实战
- 模板缓存:
django复制{% load cache %}
{% cache 600 "product_detail" product.id %}
...复杂渲染逻辑...
{% endcache %}
- 数据库优化:
- 使用
select_related和prefetch_related - 避免在循环中查询数据库
- 考虑使用
django-debug-toolbar分析
- 异步任务:
对于耗时操作(如发送邮件),使用Celery:
python复制@shared_task
def send_welcome_email(user_id):
user = User.objects.get(id=user_id)
# 发送邮件逻辑...
4. 安全防护与常见陷阱
4.1 必须防范的安全漏洞
- CSRF防护:
- 确保所有POST表单包含
{% csrf_token %} - 对API视图使用
@csrf_exempt要极其谨慎
- XSS防护:
- 除非绝对必要,否则不要使用
safe过滤器 - 用
escapejs处理JS中的动态内容
- SQL注入:
- 永远使用ORM或参数化查询
- 禁止拼接原始SQL
4.2 高并发场景应对
- 数据库层面:
- 添加适当索引
- 考虑读写分离
- 使用
select_for_update处理竞争条件
- 缓存策略:
python复制from django.core.cache import cache
def get_expensive_data():
data = cache.get('expensive_data')
if not data:
data = calculate_data()
cache.set('expensive_data', data, 3600)
return data
- 异步处理:
- 使用Celery处理后台任务
- 考虑使用Channels处理WebSocket
4.3 调试技巧宝典
- 开发服务器增强:
bash复制python manage.py runserver --nothreading --noreload
- 打印SQL日志:
python复制# settings.py
LOGGING = {
'version': 1,
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
}
},
'loggers': {
'django.db.backends': {
'level': 'DEBUG',
'handlers': ['console'],
}
}
}
- 异常捕获技巧:
python复制from django.http import Http404
def detail_view(request, pk):
try:
obj = Model.objects.get(pk=pk)
except Model.DoesNotExist:
raise Http404("不存在该对象")
return render(request, 'detail.html', {'obj': obj})
在多个日活百万级的项目中,这些Django核心功能的正确使用直接决定了系统稳定性。特别是在模板渲染优化和请求响应流程的精细控制上,往往1%的性能提升就能节省大量服务器成本
