pin_drop当前位置:知识文库 ❯ 图文
Django View视图完整教程:函数视图与类视图详解 - 零基础入门指南
目录
一、View视图概述
View(视图)是Django MVT架构中的核心组件,负责处理HTTP请求并返回HTTP响应。视图是连接URL路由和模板的桥梁,接收用户请求、处理业务逻辑、最终将结果返回给客户端。
Django支持两种视图编写风格:函数视图(FBV)和类视图(CBV)。函数视图简单直观,适合快速开发;类视图支持继承和混入(Mixin),代码复用性更高,适合大型项目。
二、函数视图(FBV)详解
函数视图是最基础的Django视图形式,使用Python函数定义,接收request对象作为第一个参数,返回HttpResponse对象。
基础函数视图
代码示例
from django.http import HttpResponse, JsonResponse
from django.shortcuts import render, redirect
def index(request):
"""首页视图"""
return HttpResponse('欢迎访问首页')
def about(request):
"""关于页面"""
context = {'title': '关于我们', 'content': '这是一个Django项目'}
return render(request, 'about.html', context)
def api_data(request):
"""API视图"""
data = {'name': 'Django', 'version': '5.0'}
return JsonResponse(data)
def redirect_view(request):
"""重定向视图"""
return redirect('/about/')
常用响应类型
函数视图可以返回多种响应类型,满足不同场景需求:
-
HttpResponse:基础响应,返回纯文本或HTML内容
-
JsonResponse:JSON格式响应,适用于API接口
-
render:渲染模板并返回HTML响应
-
redirect:HTTP重定向到另一个URL
-
HttpResponseNotFound:返回404状态码
-
HttpResponseForbidden:返回403禁止访问状态码
三、类视图(CBV)详解
类视图基于Python类实现,通过不同的方法处理不同的HTTP请求(GET、POST、PUT、DELETE等)。类视图支持继承和Mixin混入,可以大幅提高代码复用率。
基础类视图
代码示例
from django.views import View
from django.http import HttpResponse, JsonResponse
class HelloView(View):
"""基础类视图"""
def get(self, request):
return HttpResponse('Hello from CBV!')
def post(self, request):
name = request.POST.get('name', 'Guest')
return JsonResponse({'message': f'Hello, {name}!'})
类视图的URL配置
类视图在urls.py中需要使用.as_view()方法转换为可调用的视图函数:
代码示例
from django.urls import path
from .views import HelloView
urlpatterns = [
path('hello/', HelloView.as_view(), name='hello'),
]
小贴士
类视图会自动根据HTTP请求方法(GET/POST/PUT/DELETE)分发到对应的方法处理,无需手动判断request.method,这是类视图相比函数视图的一大优势。
四、HttpRequest与HttpResponse对象
HttpRequest对象属性
HttpResponse类型
五、通用类视图实战
Django提供了丰富的通用类视图(Generic Class-Based Views),可以快速实现常见的CRUD操作,大幅减少模板代码。
常用类视图类型
ListView和DetailView实战
代码示例
from django.views.generic import ListView, DetailView
from .models import Article
class ArticleListView(ListView):
"""文章列表视图"""
model = Article
template_name = 'article_list.html'
context_object_name = 'articles'
paginate_by = 10
def get_queryset(self):
return super().get_queryset().filter(status='published')
class ArticleDetailView(DetailView):
"""文章详情视图"""
model = Article
template_name = 'article_detail.html'
context_object_name = 'article'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['related_articles'] = Article.objects.filter(
category=self.object.category
).exclude(pk=self.object.pk)[:5]
return context
六、表单提交处理
使用类视图处理表单提交时,GET请求用于渲染表单页面,POST请求用于处理提交的数据。下面是一个完整的联系表单处理示例:
代码示例
from django.views import View
from django.shortcuts import render, redirect
from django.contrib import messages
class ContactView(View):
"""联系表单视图"""
def get(self, request):
return render(request, 'contact.html')
def post(self, request):
name = request.POST.get('name', '')
email = request.POST.get('email', '')
message = request.POST.get('message', '')
if not name or not email:
messages.error(request, '姓名和邮箱不能为空')
return render(request, 'contact.html', {
'name': name, 'email': email, 'message': message
})
# 处理表单数据(保存到数据库或发送邮件)...
messages.success(request, '提交成功!')
return redirect('contact')
提示:POST请求必须包含CSRF令牌,在模板中使用 {% csrf_token %} 标签生成。否则Django会拒绝该请求并返回403错误。
七、FBV与CBV对比
函数视图和类视图各有优势,选择哪种方式取决于项目的复杂度和团队偏好。
八、注意事项与最佳实践
注意:视图必须返回HttpResponse对象或其子类实例,不能返回None或普通字符串,否则会抛出异常。
注意:POST请求需要CSRF令牌保护,在HTML表单中使用 {% csrf_token %} 模板标签生成隐藏字段。
注意:类视图在urls.py中必须使用 .as_view() 方法转换为可调用对象,不能直接引用类名。
注意:在函数视图中使用 request.method 判断请求类型,而在类视图中会自动按HTTP方法分发到对应的get()、post()等方法。
小贴士
对于简单的视图(如静态页面、API接口),推荐使用函数视图,代码更简洁。对于需要复用的视图(如CRUD操作),推荐使用通用类视图,可以节省大量模板代码。
九、练习题
练习一
编写一个函数视图,接收GET请求时返回当前时间(格式为YYYY-MM-DD HH:MM:SS),接收POST请求时返回提交的表单数据(JSON格式)。
练习二
使用ListView和DetailView分别实现文章列表和文章详情页面。列表页需要支持分页(每页10条),详情页需要展示相关文章推荐。
常见问题
函数视图和类视图应该如何选择?
对于简单的视图逻辑(如返回静态页面、简单的API接口),推荐使用函数视图,代码更简洁直观。对于需要复用的视图(如CRUD操作、需要继承和混入的场景),推荐使用类视图,代码复用性更高,维护性更好。
类视图如何添加装饰器?
类视图不能直接使用装饰器,需要使用 @method_decorator 装饰器。可以在类上使用 @method_decorator(login_required, name='dispatch'),也可以在 dispatch 方法上使用。
JsonResponse和普通HttpResponse有什么区别?
JsonResponse会自动将Python字典转换为JSON字符串,并设置Content-Type为application/json。而HttpResponse需要手动序列化JSON并设置Content-Type,JsonResponse更加方便快捷。
通用类视图如何自定义查询集?
重写 get_queryset() 方法可以自定义查询集。例如在ListView中,可以返回过滤后的查询集:def get_queryset(self): return Article.objects.filter(status='published')。
视图返回404状态码的最佳实践是什么?
推荐使用 get_object_or_404() 快捷函数,它会在对象不存在时自动抛出Http404异常。也可以使用 HttpResponseNotFound 直接返回404响应,但前者更加简洁。
本文涉及AI创作
内容由AI创作,请仔细甄别