从入门到精通:Django的深度探索之旅

文章目录

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;原文链接:发布后补充。

参考资料

推荐阅读与后续

相关推荐
IT_陈寒11 分钟前
Redis持久化这个坑,我爬了一整天才出来
前端·人工智能·后端
无风听海11 分钟前
多租户系统中的 OIDC:Discovery 端点与联合登录的深度实践
后端·python·flask
CTA终结者42 分钟前
期货量化主力换月程序怎么移仓:天勤 underlying_symbol 与任务切换
python·区块链
小小前端仔LC44 分钟前
Node.js + LangChain + React:搭建个人知识库(六)- “吃什么”项目实战:从700+菜谱入库到Taro H5端JSON渲染
前端·后端
huangdong_44 分钟前
1688商品图片采集技术解析:登录态处理与SKU图自动分类
开发语言
马士兵教育1 小时前
Java还有前景吗?Java+AI大模型学习路线及项目?
java·人工智能·python·学习·机器学习
chase_my_dream1 小时前
C++ + SLAM 高频面试问题整理
开发语言·c++·面试
程序员黑豆1 小时前
AI全栈开发之Java:怎么配置Java环境变量
前端·后端·ai编程
KaMeidebaby1 小时前
卡梅德生物技术快报|纯化重组蛋白实操详解
人工智能·python·tcp/ip·算法·机器学习
Cloud_Shy6181 小时前
解读《Effective Python 3rd Edition》:从练气到老魔(第五章 Item 30 - 32)
开发语言·人工智能·笔记·python·学习方法