django View视图层详解
课程目标
- 理解django视图的概念和作用
- 掌握函数视图和类视图的使用
- 学会处理HTTP请求和响应
- 了解django的URL配置机制
视图简介
django视图是处理HTTP请求并返回HTTP响应的函数或类,位于django MTV架构的"V"层(View),是连接用户输入、业务逻辑、页面展示的核心纽带。
视图的核心职责:
- 接收并解析浏览器发来的HTTP请求
- 调用模型层、服务层处理业务逻辑(如数据增删改查)
- 生成符合要求的HTTP响应返回给浏览器
函数视图(Function-Based Views)
函数视图是django最早也是最直观的视图形式——一个Python函数对应一个URL路由,适合逻辑简单或高度自定义的场景。
基础无模板视图
直接返回HTML字符串或纯文本,适合调试或极简接口:
from django.http import HttpResponse
import datetime
def current_datetime(request):
# request是django自动传入的HttpRequest对象,包含所有请求信息
now = datetime.datetime.now()
html = f"<html><body>现在是 {now.strftime('%Y-%m-%d %H:%M:%S')}</body></html>"
return HttpResponse(html)
结合模板的视图
用django.shortcuts.render快速渲染HTML模板(MTV架构的核心体现,把视图逻辑和页面展示分离):
from django.shortcuts import render
# 假设已定义好Article模型
def article_list(request):
articles = Article.objects.filter(is_published=True).order_by("-pub_date")[:10]
# context字典用于向模板传递变量
context = {"articles": articles}
return render(request, "articles/list.html", context)
处理表单POST请求
通过request.method区分请求类型,配合messages框架和redirect实现完整的表单流程:
from django.shortcuts import render, redirect
from django.contrib import messages
from django.contrib.auth.decorators import login_required
@login_required # 强制登录
def create_article(request):
if request.method == "POST":
# 获取POST表单数据(get的第二个参数是默认值)
title = request.POST.get("title", "").strip()
content = request.POST.get("content", "").strip()
if not title or not content:
messages.error(request, "标题和内容不能为空")
return render(request, "articles/create.html")
# 保存到数据库
Article.objects.create(
title=title,
content=content,
author=request.user,
is_published=True
)
messages.success(request, "文章发布成功!")
# 重定向到列表页(避免表单重复提交)
return redirect("article_list")
# GET请求直接返回空表单
return render(request, "articles/create.html")
类视图(Class-Based Views)
类视图用面向对象的方式组织代码,自带很多通用场景的封装,可以大幅减少重复代码,适合CRUD(增删改查)、分页等标准化场景。
基础View类视图
继承django.views.View,通过重写HTTP方法名对应的函数(如get()、post())处理请求:
from django.views import View
from django.http import HttpResponse
class HelloView(View):
def get(self, request):
return HttpResponse("Hello, Class-Based Views!")
def post(self, request):
return HttpResponse("Received POST from CBV")
通用视图(Generic Views)
django内置了一套封装好的通用类视图,直接覆盖属性或轻量重写方法即可使用:
from django.views.generic import ListView, DetailView, CreateView
from django.urls import reverse_lazy
from django.contrib.auth.mixins import LoginRequiredMixin
class ArticleListView(ListView):
model = Article # 指定操作的模型
template_name = "articles/list.html" # 指定渲染的模板
context_object_name = "articles" # 指定传递给模板的变量名(默认是object_list)
paginate_by = 10 # 开启分页,每页10条
# 重写get_queryset自定义查询条件(默认是model.objects.all())
def get_queryset(self):
return Article.objects.filter(is_published=True).order_by("-pub_date")
class ArticleDetailView(DetailView):
model = Article
template_name = "articles/detail.html"
context_object_name = "article"
pk_url_kwarg = "article_id" # 指定URL参数名(默认是pk)
# LoginRequiredMixin放在前面,强制类视图登录
class ArticleCreateView(LoginRequiredMixin, CreateView):
model = Article
fields = ["title", "content", "category"] # 指定表单字段
template_name = "articles/create.html"
success_url = reverse_lazy("article_list") # 成功后跳转的URL(reverse_lazy适合类视图延迟解析)
# 重写form_valid自定义保存逻辑(默认只保存表单字段)
def form_valid(self, form):
form.instance.author = self.request.user
form.instance.is_published = True
return super().form_valid(form)
HTTP请求与响应处理
django封装了完整的HttpRequest(请求)和HttpResponse(响应)体系,我们只需要操作这两个对象即可。
HttpRequest常用属性
def handle_request(request):
# 请求方法:GET/POST/PUT/DELETE等
method = request.method
# GET查询参数(如?search=python)
search_keyword = request.GET.get("search", "")
# POST表单数据
username = request.POST.get("username", "")
# 请求头信息(注意HTTP前缀,且转成大写加下划线)
user_agent = request.META.get("HTTP_USER_AGENT", "未知浏览器")
client_ip = request.META.get("REMOTE_ADDR", "")
# 用户与会话信息(需启用Auth和Session中间件)
is_logged_in = request.user.is_authenticated
cart_count = request.session.get("cart_count", 0)
常用HttpResponse子类
from django.http import (
HttpResponse,
JsonResponse,
HttpResponseRedirect,
HttpResponseNotFound
)
from django.shortcuts import redirect, get_object_or_404
def response_demo(request):
# 1. 纯文本/HTML响应
text_resp = HttpResponse("这是纯文本响应")
html_resp = HttpResponse("<h1>这是HTML响应</h1>", content_type="text/html")
# 2. JSON响应(自动设置content_type为application/json,且safe=False允许非字典类型)
json_resp = JsonResponse({"status": "success", "data": [1,2,3]}, safe=False)
# 3. 重定向响应(推荐用redirect快捷函数,支持URL名称和对象)
redirect_by_name = redirect("article_list")
redirect_by_obj = redirect(Article.objects.first())
redirect_raw = HttpResponseRedirect("/articles/")
# 4. 404响应(推荐用get_object_or_404快捷函数自动触发)
article = get_object_or_404(Article, id=999)
manual_404 = HttpResponseNotFound("页面走丢了")
URL配置机制
django通过URLconf模块(通常是项目的urls.py和各应用的urls.py)把URL路径映射到对应的视图。
基础URL模式
# 项目的根urls.py
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path("admin/", admin.site.urls), # 管理后台
path("articles/", include("articles.urls")), # 包含应用的子路由
]
# articles应用的子urls.py
from django.urls import path
from . import views
urlpatterns = [
# 函数视图映射
path("", views.article_list, name="article_list"),
path("<int:article_id>/", views.article_detail, name="article_detail"),
# 类视图映射(必须调用.as_view()方法)
path("create/", views.ArticleCreateView.as_view(), name="article_create"),
]
URL参数类型
django内置了几种常用的路径转换器:
<int:id>:匹配整数
<slug:slug>:匹配slug字符串(字母、数字、下划线、连字符)
<str:title>:匹配除路径分隔符/外的所有字符串(默认类型)
<uuid:uuid>:匹配UUID
<path:path>:匹配包含路径分隔符/的所有字符串
装饰器与最佳实践
常用视图装饰器
装饰器可以快速给视图添加额外功能,函数视图直接用@装饰器,类视图用method_decorator或混入(Mixin):
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods, require_POST
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
# 函数视图装饰器
@login_required
@require_POST
def delete_article(request, article_id):
# 处理删除逻辑
pass
@csrf_exempt # 仅用于第三方Webhook等无需CSRF的场景
def wechat_webhook(request):
# 处理微信回调
pass
# 类视图装饰器(用method_decorator)
@method_decorator(login_required, name="dispatch")
class ArticleUpdateView(View):
def get(self, request):
pass
视图最佳实践
- 保持视图简洁:复杂的业务逻辑移到模型层的方法、或独立的服务层
- 合理使用通用视图:CRUD、分页等场景优先用通用类视图
- 正确处理异常:用
get_object_or_404、get_list_or_404替代手动抛出404
- 避免表单重复提交:POST请求处理成功后必须重定向(PRG模式)
- 使用适当的状态码:如403(权限不足)、405(方法不允许)、201(创建成功)
课程总结
本节课我们系统学习了django视图层的核心内容:
- 视图的概念和职责
- 函数视图的基础、模板、表单处理
- 类视图的基础、通用类视图(CRUD、分页等)
- HttpRequest和HttpResponse的常用操作
- URLconf的配置和路径转换器
- 常用装饰器和视图最佳实践
视图是django应用的核心入口,掌握视图的使用对构建任何Web应用都至关重要。下节课我们将学习django的模板层!