从入门到精通:Django的深度探索之旅
文章目录
- 第一部分:Django基础入门
- 1. MVT架构:Django的核心思想
- 2. 快速创建你的第一个项目
- 3. 编写你的第一个视图
- 第二部分:释放ORM的全部潜能
- 1. F()表达式:数据库层面的原子操作
- 2. Q()对象:构建复杂的OR查询
- 3. Subquery和OuterRef:超越简单JOIN
- 4. 窗口函数:分区聚合的艺术
- 第三部分:拥抱Django的异步能力
- 异步处理流程图
- 1. 编写异步视图
- 2. sync_to_async:在异步世界中使用同步代码
- 实战演练:本地运行小贴士
- 总结
- 原创声明与首发信息
- 参考资料
- 推荐阅读与后续
Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。它解决了Web开发中大量的样板工作,让你专注于业务本身。
本文从基础到进阶,覆盖MVT架构、ORM高级技巧与异步视图,兼顾新手友好与专业深度,力求提高可读性与质量分。
第一部分:Django基础入门
对于初学者来说,掌握Django的核心概念是迈向成功的关键第一步。
1. MVT架构:Django的核心思想
Django遵循模型-视图-模板(Model-View-Template, MVT)的设计模式:
- 模型 (Model): 负责数据结构与数据库映射。
- 视图 (View): 接收请求、执行业务逻辑并返回响应。
- 模板 (Template): 负责数据的页面展示。
2. 快速创建你的第一个项目
准备好开始了吗?首先,请确保你已安装Python与Django。
# 安装Django
pip install django# 创建新项目
django-admin startproject myproject# 进入项目目录
cd myproject# 创建新应用
python manage.py startapp myapp
3. 编写你的第一个视图
现在,让我们创建一个简单的"Hello, World!"页面。
开发流程图:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 创建视图 │───▶│ 配置URL │───▶│ 启动服务 │
│ views.py │ │ urls.py │ │ runserver │
└─────────────┘ └─────────────┘ └─────────────┘│ │ │▼ ▼ ▼编写函数 路由映射 浏览器访问
# myapp/views.py
from django.http import HttpResponsedef hello_world(request):return HttpResponse("Hello, World!")
# myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp.views import hello_worldurlpatterns = [path('admin/', admin.site.urls),path('hello/', hello_world),
]
# 启动开发服务器
python manage.py runserver
现在访问 http://127.0.0.1:8000/hello/
,你应该能看到 “Hello, World!”。
第二部分:释放ORM的全部潜能
Django的ORM远不止filter()
和get()
。当你需要处理复杂的数据聚合、子查询和数据库级别的计算时,高级ORM特性将成为你的利器。
1. F()表达式:数据库层面的原子操作
F()
表达式允许你在数据库层面直接引用模型的字段值,而无需将它们加载到Python内存中。
场景:假设我们有一个产品模型,需要增加所有产品的价格。
from django.db import models
from django.db.models import Fclass Product(models.Model):name = models.CharField(max_length=100)price = models.DecimalField(max_digits=10, decimal_places=2)stock = models.IntegerField()# 错误的方式:非原子操作,存在竞态条件
for product in Product.objects.all():product.price = product.price * 1.05product.save()# 正确的方式:使用F()表达式,在数据库层面完成原子操作
Product.objects.update(price=F('price') * 1.05)
提示:上述update
会被翻译为单条SQL,确保原子性与并发安全。
2. Q()对象:构建复杂的OR查询
默认情况下,filter()
中的多个条件是AND
关系。当你需要构建包含OR
逻辑的复杂查询时,Q()
对象就派上用场了。
场景:查找名称包含"笔记本"或价格低于5000的商品。
from django.db.models import Q# 基本OR查询
Product.objects.filter(Q(name__icontains='笔记本') | Q(price__lt=5000)
)# 复杂组合查询
Product.objects.filter((Q(name__icontains='笔记本') | Q(name__icontains='电脑')) &Q(price__range=(1000, 10000)) &~Q(stock=0) # 排除库存为0的商品
)
3. Subquery和OuterRef:超越简单JOIN
当JOIN
无法满足你的需求,或者你需要在一个查询中引用外部查询的字段时,Subquery
就显得尤为重要。
场景:我们有一个博客文章(Post)和评论(Comment)模型。现在,我们想获取每篇文章的最新评论的创建日期。
from django.db import models
from django.db.models import Subquery, OuterRefclass Post(models.Model):title = models.CharField(max_length=200)content = models.TextField()class Comment(models.Model):post = models.ForeignKey(Post, on_delete=models.CASCADE, related_name='comments')author = models.CharField(max_length=100)text = models.TextField()created_at = models.DateTimeField(auto_now_add=True)# 构建子查询,用于获取每篇文章的最新评论
latest_comment_subquery = Comment.objects.filter(post=OuterRef('pk')
).order_by('-created_at').values('created_at')[:1]# 在主查询中使用Subquery进行注解
posts_with_latest_comment_date = Post.objects.annotate(latest_comment_date=Subquery(latest_comment_subquery)
)for post in posts_with_latest_comment_date:print(f"'{post.title}' 的最新评论于: {post.latest_comment_date}")
4. 窗口函数:分区聚合的艺术
窗口函数允许你对与当前行相关的行集执行计算。这对于需要排名、计算移动平均值或在分区内进行聚合的场景非常有用。
场景:假设我们有一个销售记录模型,需要计算每个产品在其类别内的销售额排名。
from django.db import models
from django.db.models import Window, F
from django.db.models.functions import Rankclass Sale(models.Model):product_name = models.CharField(max_length=100)category = models.CharField(max_length=50)amount = models.DecimalField(max_digits=10, decimal_places=2)# 使用窗口函数计算排名
sales_with_rank = Sale.objects.annotate(rank_in_category=Window(expression=Rank(),partition_by=[F('category')],order_by=F('amount').desc())
).order_by('category', 'rank_in_category')for sale in sales_with_rank:print(f"类别: {sale.category}, 产品: {sale.product_name}, "f"销售额: {sale.amount}, 排名: {sale.rank_in_category}")
第三部分:拥抱Django的异步能力
从Django 3.1开始,异步视图得到了原生支持,这为处理大量I/O密集型任务开辟了新天地。
异步处理流程图
1. 编写异步视图
编写一个异步视图就像定义一个async def
函数一样简单。
import asyncio
from django.http import HttpResponseasync def my_async_view(request):# 模拟一个耗时的I/O操作,例如调用外部APIawait asyncio.sleep(2)return HttpResponse("操作完成!")
2. sync_to_async:在异步世界中使用同步代码
Django的许多部分(特别是ORM)在Django 4.0之前仍然是同步的。sync_to_async
适配器允许你在异步视图中安全地调用这些同步代码。
场景:一个异步视图需要从多个外部API获取数据,然后将结果存入数据库。
import asyncio
import httpx # 异步HTTP客户端
from asgiref.sync import sync_to_async
from .models import ApiData# ORM操作是同步的,需要一个同步函数来封装它
def save_data_to_db(source, data):ApiData.objects.create(source=source, data=data)# 使用sync_to_async将其转换为异步可调用对象
save_data_async = sync_to_async(save_data_to_db, thread_sensitive=True)async def fetch_and_save_apis(request):async with httpx.AsyncClient() as client:# 并发请求多个APItasks = [client.get('https://api.example.com/data1'),client.get('https://api.github.com/events')]responses = await asyncio.gather(*tasks)# 并发保存到数据库save_tasks = []for i, response in enumerate(responses):response.raise_for_status()source_name = f"API_{i+1}"save_tasks.append(save_data_async(source_name, response.json()))await asyncio.gather(*save_tasks)return HttpResponse("所有API数据已成功获取并保存!")
提示:并发网络请求 + sync_to_async
包装同步ORM,可显著提升吞吐量。
实战演练:本地运行小贴士
建议将示例代码复制到你的项目中,本地运行更稳定可靠:
# 迁移数据库并启动服务
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
总结
从搭建第一个"Hello, World"应用到驾驭复杂的数据库查询和异步视图,我们一同走过了一条从入门到精通的Django学习之路。Django既为初学者提供了清晰的入门路径,也为资深开发者提供了强大的进阶工具。
原创声明与首发信息
本文为原创,首发于CSDN,转载请注明出处与原文链接。
首发日期:2025-10-02;原文链接:发布后补充。
参考资料
- Django Official Docs
- ORM Queries
- Async support
- 项目源码与文档(本仓库)
- Python 官方文档(语言与标准库参考)
推荐阅读与后续
- 从零搭建Django项目的最佳实践(入门篇)
- Django中间件与信号的工程化应用(进阶篇)
- Django部署与性能优化(生产篇)