Django视图与路由系统

一、Django视图系统详解

1.1 视图基础概念

视图(View)是Django的核心组件之一,负责处理Web请求并返回响应。它可以是一个Python函数(FBV)或一个类(CBV),通常存放在views.py文件中。

视图的基本职责

  • 接收HttpRequest对象作为参数

  • 处理业务逻辑

  • 返回HttpResponse对象或其子类

1.2 函数视图(FBV)示例

复制代码
from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = f"<html><body>当前时间: {now}</body></html>"
    return HttpResponse(html)

1.3 类视图(CBV)示例

复制代码
from django.views import View
from django.shortcuts import render, redirect

class AddPress(View):
    def get(self, request):
        return render(request, 'add_press.html')
    
    def post(self, request):
        press_name = request.POST.get('name')
        Press.objects.create(name=press_name)
        return redirect('/press_list/')

FBV与CBV对比

类型 优点 缺点 适用场景
FBV 简单直观,适合简单逻辑 代码复用性差 简单页面、快速开发
CBV 代码复用高,结构清晰 学习曲线稍高 复杂业务、需要复用逻辑

二、Request对象深度解析

2.1 常用Request属性

属性 描述 示例
request.method 请求方法(GET/POST等) if request.method == 'POST':
request.GET GET请求参数(类字典对象) id = request.GET.get('id')
request.POST POST请求参数(类字典对象) name = request.POST.get('name')
request.FILES 上传的文件对象 file = request.FILES['file']
request.path 请求路径(不含域名) /articles/2023/
request.META 请求头信息 ip = request.META.get('REMOTE_ADDR')

2.2 常用Request方法

方法 描述 示例
get_full_path() 获取完整路径(含查询参数) /articles/?page=2
is_ajax() 判断是否AJAX请求 if request.is_ajax():
get_host() 获取请求的主机 127.0.0.1:8000

2.3 处理多值参数

对于多选框等场景,使用getlist()获取多个值:

复制代码
hobbies = request.POST.getlist('hobbies')

三、Response对象全解析

3.1 HttpResponse基础

复制代码
response = HttpResponse("文本内容", content_type="text/plain")
response.status_code = 200  # 设置状态码
response['X-Custom-Header'] = 'value'  # 设置响应头

3.2 常用快捷响应

3.2.1 render() - 渲染模板
复制代码
from django.shortcuts import render

def my_view(request):
    return render(request, 'template.html', 
                 {'data': 'value'}, 
                 content_type='text/html', 
                 status=200)
3.2.2 redirect() - 重定向
复制代码
from django.shortcuts import redirect

def my_view(request):
    # 重定向到URL
    return redirect('/some/url/')
    # 重定向到视图名
    return redirect('view_name')
    # 重定向到模型(调用get_absolute_url)
    return redirect(some_object)
3.2.3 JsonResponse - JSON响应
复制代码
from django.http import JsonResponse

def my_view(request):
    data = {'key': 'value'}
    return JsonResponse(data)
    
    # 非字典数据需要设置safe=False
    return JsonResponse([1, 2, 3], safe=False)

四、Django路由系统详解

4.1 URL配置基础

基本结构

复制代码
from django.urls import path
from . import views

urlpatterns = [
    path('articles/2023/', views.special_case_2023),
    path('articles/<int:year>/', views.year_archive),
    path('articles/<int:year>/<int:month>/', views.month_archive),
]

4.2 路径转换器

Django内置路径转换器:

转换器 说明 示例
str 匹配非空字符串(默认) path('<str:name>/', ...)
int 匹配正整数 path('<int:id>/', ...)
slug 匹配字母、数字、连字符 path('<slug:title>/', ...)
uuid 匹配UUID字符串 path('<uuid:uid>/', ...)
path 匹配包含/的字符串 path('<path:url>/', ...)

4.3 正则表达式路由

使用re_path实现复杂匹配:

复制代码
from django.urls import re_path

urlpatterns = [
    re_path(r'articles/(?P<year>[0-9]{4})/$', views.year_archive),
    re_path(r'articles/(?P<year>[0-9]{4})/(?P<month>[0-9]{2})/$', views.month_archive),
]

4.4 URL命名与反向解析

1. 命名URL

复制代码
path('articles/<int:year>/', views.year_archive, name='news-year-archive')

2. 模板中反向解析

复制代码
<a href="{% url 'news-year-archive' 2023 %}">2023 Archive</a>

3. Python代码中反向解析

复制代码
from django.urls import reverse

reverse('news-year-archive', args=[2023])

4.5 URL命名空间

解决不同app间URL名称冲突问题:

复制代码
# 主urls.py
path('app01/', include('app01.urls', namespace='app01'))

# 模板中使用
{% url 'app01:view-name' %}

# Python代码中使用
reverse('app01:view-name')

五、实战案例

5.1 综合视图示例

复制代码
from django.views import View
from django.shortcuts import render, redirect
from django.urls import reverse
from .models import Article
from django.http import JsonResponse

class ArticleView(View):
    def get(self, request, article_id):
        article = Article.objects.get(id=article_id)
        return render(request, 'article_detail.html', {'article': article})
    
    def post(self, request, article_id):
        title = request.POST.get('title')
        content = request.POST.get('content')
        Article.objects.filter(id=article_id).update(
            title=title,
            content=content
        )
        return redirect(reverse('article-detail', args=[article_id]))
    
    def delete(self, request, article_id):
        Article.objects.filter(id=article_id).delete()
        return JsonResponse({'status': 'success'})

5.2 URL配置示例

复制代码
from django.urls import path, re_path
from . import views

urlpatterns = [
    path('articles/', views.ArticleListView.as_view(), name='article-list'),
    path('articles/create/', views.ArticleCreateView.as_view(), name='article-create'),
    re_path(r'^articles/(?P<pk>[0-9]+)/$', 
           views.ArticleDetailView.as_view(), 
           name='article-detail'),
    path('api/articles/', views.article_api, name='article-api'),
]

六、高级技巧与最佳实践

6.1 视图装饰器

复制代码
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods

@login_required
@require_http_methods(["GET", "POST"])
def my_view(request):
    # 仅允许已登录用户通过GET或POST方法访问
    pass

6.2 自定义路径转换器

复制代码
# converters.py
class FourDigitYearConverter:
    regex = '[0-9]{4}'
    
    def to_python(self, value):
        return int(value)
    
    def to_url(self, value):
        return '%04d' % value

# urls.py
from django.urls import register_converter, path
from . import converters, views

register_converter(converters.FourDigitYearConverter, 'yyyy')

urlpatterns = [
    path('articles/<yyyy:year>/', views.year_archive),
]

6.3 性能优化建议

  1. 合理使用select_related/prefetch_related:减少数据库查询

  2. 启用缓存:对频繁访问的视图使用缓存

  3. 异步处理:耗时操作使用Celery等异步任务队列

  4. 分页处理:大数据集使用分页

通过本指南,您应该已经掌握了Django视图和路由系统的核心概念与实用技巧。建议结合官方文档和实际项目练习,以加深理解并提高开发效率。

相关推荐
叫我:松哥12 小时前
基于python django深度学习的中文文本检测+识别,可以前端上传图片和后台管理图片
图像处理·人工智能·后端·python·深度学习·数据挖掘·django
小王子10241 天前
Django集成Swagger全指南:两种实用方案详解
django·swagger·openapi
言之。2 天前
Django Ninja
后端·python·django
言之。2 天前
深入解析 Django REST Framework 的 APIView 核心方法
数据库·django·sqlite
小王子10242 天前
Django集成Swagger全指南:两种实现方案详解
django·swagger·openapi
程序员的世界你不懂2 天前
Django接口自动化平台实现(四)
python·django·自动化
PythonicCC2 天前
Django ORM系统
数据库·django
万粉变现经纪人3 天前
如何解决pip安装报错ModuleNotFoundError: No module named ‘django’问题
后端·python·pycharm·django·numpy·pandas·pip
程序设计实验室3 天前
使用django-simple-history实现简单审计功能
django·djangostarter