第6章:Django视图(Views)
6.1 函数视图
基本函数视图
在Django中,视图是处理HTTP请求并返回HTTP响应的Python函数。函数视图是最简单的视图形式。
一个基本的函数视图示例:
python
from django.http import HttpResponse
def hello(request):
return HttpResponse("Hello, World!")这个简单的视图函数接收一个HttpRequest对象作为参数,并返回一个HttpResponse对象。
HttpRequest和HttpResponse
HttpRequest对象包含客户端发送的所有HTTP请求信息,包括:
request.method: HTTP方法(GET, POST等)request.GET: URL参数request.POST: POST数据request.COOKIES: Cookie信息request.META: HTTP头部信息
HttpResponse对象用于构建返回给客户端的HTTP响应:
python
from django.http import HttpResponse
def my_view(request):
# 创建一个简单的HTTP响应
response = HttpResponse("Hello, World!")
# 设置HTTP头部
response['Content-Type'] = 'text/plain'
return response视图装饰器
Django提供了许多内置装饰器来增强视图功能:
python
from django.contrib.auth.decorators import login_required
from django.views.decorators.http import require_http_methods
# 限制HTTP方法
@require_http_methods(["GET", "POST"])
def my_view(request):
if request.method == 'GET':
return HttpResponse("GET request")
elif request.method == 'POST':
return HttpResponse("POST request")
# 要求用户登录
@login_required
def protected_view(request):
return HttpResponse(f"Hello, {request.user.username}!")错误处理
Django提供了处理常见HTTP错误的异常类:
python
from django.http import HttpResponse, Http404
from django.core.exceptions import PermissionDenied
def article_detail(request, article_id):
try:
# 尝试获取文章
article = Article.objects.get(id=article_id)
except Article.DoesNotExist:
# 抛出404错误
raise Http404("Article does not exist")
# 检查权限
if not request.user.has_perm('app.view_article'):
raise PermissionDenied("You don't have permission to view this article")
return HttpResponse(f"Article: {article.title}")6.2 类视图
View基类
Django提供了基于类的视图(Class-Based Views, CBV),相比函数视图更加灵活和可重用:
python
from django.views import View
from django.http import HttpResponse
class MyView(View):
def get(self, request):
return HttpResponse("GET request")
def post(self, request):
return HttpResponse("POST request")通用视图概念
Django提供了许多通用视图类来处理常见的Web开发任务,如显示对象列表、详情页面等。
TemplateView示例
TemplateView用于渲染模板:
python
from django.views.generic import TemplateView
class HomePageView(TemplateView):
template_name = "home.html"
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['latest_articles'] = Article.objects.all()[:5]
return context继承和混入
Django的类视图支持多重继承,可以使用Mixin类来添加功能:
python
from django.contrib.auth.mixins import LoginRequiredMixin
from django.views.generic import ListView
class ProtectedListView(LoginRequiredMixin, ListView):
login_url = '/login/'
redirect_field_name = 'redirect_to'6.3 通用视图详解
ListView
ListView用于显示对象列表:
python
from django.views.generic import ListView
from .models import Article
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles'
paginate_by = 10 # 每页显示10个项目DetailView
DetailView用于显示单个对象的详细信息:
python
from django.views.generic import DetailView
from .models import Article
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/article_detail.html'
context_object_name = 'article'CreateView
CreateView用于创建新对象:
python
from django.views.generic import CreateView
from .models import Article
from .forms import ArticleForm
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = '/articles/'UpdateView
UpdateView用于更新现有对象:
python
from django.views.generic import UpdateView
from .models import Article
class ArticleUpdateView(UpdateView):
model = Article
fields = ['title', 'content']
template_name = 'articles/article_form.html'
success_url = '/articles/'DeleteView
DeleteView用于删除对象:
python
from django.views.generic import DeleteView
from .models import Article
from django.urls import reverse_lazy
class ArticleDeleteView(DeleteView):
model = Article
template_name = 'articles/article_confirm_delete.html'
success_url = reverse_lazy('article_list')完整CRUD示例
以下是一个完整的博客文章CRUD示例:
python
# views.py
from django.views.generic import ListView, DetailView, CreateView, UpdateView, DeleteView
from django.urls import reverse_lazy
from .models import Article
from .forms import ArticleForm
class ArticleListView(ListView):
model = Article
template_name = 'articles/article_list.html'
context_object_name = 'articles'
ordering = ['-created_at']
class ArticleDetailView(DetailView):
model = Article
template_name = 'articles/article_detail.html'
context_object_name = 'article'
class ArticleCreateView(CreateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = reverse_lazy('article_list')
class ArticleUpdateView(UpdateView):
model = Article
form_class = ArticleForm
template_name = 'articles/article_form.html'
success_url = reverse_lazy('article_list')
class ArticleDeleteView(DeleteView):
model = Article
template_name = 'articles/article_confirm_delete.html'
success_url = reverse_lazy('article_list')对应的URL配置:
python
# urls.py
from django.urls import path
from . import views
urlpatterns = [
path('articles/', views.ArticleListView.as_view(), name='article_list'),
path('articles/<int:pk>/', views.ArticleDetailView.as_view(), name='article_detail'),
path('articles/new/', views.ArticleCreateView.as_view(), name='article_create'),
path('articles/<int:pk>/edit/', views.ArticleUpdateView.as_view(), name='article_update'),
path('articles/<int:pk>/delete/', views.ArticleDeleteView.as_view(), name='article_delete'),
]小结
Django视图是处理用户请求的核心组件:
- ✅ 函数视图适合简单逻辑,易于理解和实现
- ✅ 类视图提供更好的代码重用和组织
- ✅ 通用视图大大减少重复代码
- ✅ 装饰器和Mixin增强视图功能
- ✅ 完整的CRUD操作支持
合理选择视图类型能够提高开发效率和代码质量。
下一篇
我们将学习如何使用通用视图和自定义模板标签来构建更复杂的Web应用。