文章目录
-
- 第一部分:Django基础入门
-
- [1. MVT架构:Django的核心思想](#1. MVT架构:Django的核心思想)
- [2. 快速创建你的第一个项目](#2. 快速创建你的第一个项目)
- [3. 编写你的第一个视图](#3. 编写你的第一个视图)
- 第二部分:释放ORM的全部潜能
-
- [1. F()表达式:数据库层面的原子操作](#1. F()表达式:数据库层面的原子操作)
- [2. Q()对象:构建复杂的OR查询](#2. Q()对象:构建复杂的OR查询)
- [3. Subquery和OuterRef:超越简单JOIN](#3. Subquery和OuterRef:超越简单JOIN)
- [4. 窗口函数:分区聚合的艺术](#4. 窗口函数:分区聚合的艺术)
- 第三部分:拥抱Django的异步能力
-
- 异步处理流程图
- [1. 编写异步视图](#1. 编写异步视图)
- [2. sync_to_async:在异步世界中使用同步代码](#2. sync_to_async:在异步世界中使用同步代码)
- 实战演练:本地运行小贴士
- 总结
- 原创声明与首发信息
- 参考资料
- 推荐阅读与后续

Django是一个高级的Python Web框架,它鼓励快速开发和干净、实用的设计。它解决了Web开发中大量的样板工作,让你专注于业务本身。
本文从基础到进阶,覆盖MVT架构、ORM高级技巧与异步视图,兼顾新手友好与专业深度,力求提高可读性与质量分。
第一部分:Django基础入门
对于初学者来说,掌握Django的核心概念是迈向成功的关键第一步。
1. MVT架构:Django的核心思想
Django遵循模型-视图-模板(Model-View-Template, MVT)的设计模式:
用户请求 URL路由 视图 View 模型 Model 数据库 模板 Template HTML响应 用户浏览器
- 模型 (Model): 负责数据结构与数据库映射。
- 视图 (View): 接收请求、执行业务逻辑并返回响应。
- 模板 (Template): 负责数据的页面展示。
2. 快速创建你的第一个项目
准备好开始了吗?首先,请确保你已安装Python与Django。
bash
# 安装Django
pip install django
# 创建新项目
django-admin startproject myproject
# 进入项目目录
cd myproject
# 创建新应用
python manage.py startapp myapp
3. 编写你的第一个视图
现在,让我们创建一个简单的"Hello, World!"页面。
开发流程图:
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 创建视图 │───▶│ 配置URL │───▶│ 启动服务 │
│ views.py │ │ urls.py │ │ runserver │
└─────────────┘ └─────────────┘ └─────────────┘
│ │ │
▼ ▼ ▼
编写函数 路由映射 浏览器访问
python
# myapp/views.py
from django.http import HttpResponse
def hello_world(request):
return HttpResponse("Hello, World!")
python
# myproject/urls.py
from django.contrib import admin
from django.urls import path
from myapp.views import hello_world
urlpatterns = [
path('admin/', admin.site.urls),
path('hello/', hello_world),
]
bash
# 启动开发服务器
python manage.py runserver
现在访问 http://127.0.0.1:8000/hello/
,你应该能看到 "Hello, World!"。
第二部分:释放ORM的全部潜能
Django的ORM远不止filter()
和get()
。当你需要处理复杂的数据聚合、子查询和数据库级别的计算时,高级ORM特性将成为你的利器。
1. F()表达式:数据库层面的原子操作
F()
表达式允许你在数据库层面直接引用模型的字段值,而无需将它们加载到Python内存中。
场景:假设我们有一个产品模型,需要增加所有产品的价格。
python
from django.db import models
from django.db.models import F
class 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.05
product.save()
# 正确的方式:使用F()表达式,在数据库层面完成原子操作
Product.objects.update(price=F('price') * 1.05)
提示:上述update
会被翻译为单条SQL,确保原子性与并发安全。
2. Q()对象:构建复杂的OR查询
默认情况下,filter()
中的多个条件是AND
关系。当你需要构建包含OR
逻辑的复杂查询时,Q()
对象就派上用场了。
场景:查找名称包含"笔记本"或价格低于5000的商品。
python
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)模型。现在,我们想获取每篇文章的最新评论的创建日期。
python
from django.db import models
from django.db.models import Subquery, OuterRef
class 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. 窗口函数:分区聚合的艺术
窗口函数允许你对与当前行相关的行集执行计算。这对于需要排名、计算移动平均值或在分区内进行聚合的场景非常有用。
场景:假设我们有一个销售记录模型,需要计算每个产品在其类别内的销售额排名。
python
from django.db import models
from django.db.models import Window, F
from django.db.models.functions import Rank
class 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密集型任务开辟了新天地。
异步处理流程图
客户端 异步视图 外部API1 外部API2 数据库 发送请求 异步调用API1 异步调用API2 返回数据1 返回数据2 par [并发处理] 异步保存数据 保存完成 返回响应 客户端 异步视图 外部API1 外部API2 数据库
1. 编写异步视图
编写一个异步视图就像定义一个async def
函数一样简单。
python
import asyncio
from django.http import HttpResponse
async def my_async_view(request):
# 模拟一个耗时的I/O操作,例如调用外部API
await asyncio.sleep(2)
return HttpResponse("操作完成!")
2. sync_to_async:在异步世界中使用同步代码
Django的许多部分(特别是ORM)在Django 4.0之前仍然是同步的。sync_to_async
适配器允许你在异步视图中安全地调用这些同步代码。
场景:一个异步视图需要从多个外部API获取数据,然后将结果存入数据库。
python
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:
# 并发请求多个API
tasks = [
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,可显著提升吞吐量。
实战演练:本地运行小贴士
建议将示例代码复制到你的项目中,本地运行更稳定可靠:
bash
# 迁移数据库并启动服务
python manage.py makemigrations
python manage.py migrate
python manage.py runserver
总结
从搭建第一个"Hello, World"应用到驾驭复杂的数据库查询和异步视图,我们一同走过了一条从入门到精通的Django学习之路。Django既为初学者提供了清晰的入门路径,也为资深开发者提供了强大的进阶工具。
原创声明与首发信息
本文为原创,首发于CSDN,转载请注明出处与原文链接。
首发日期:2025-10-02;原文链接:发布后补充。