Skip to content

第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视图是处理用户请求的核心组件:

  1. ✅ 函数视图适合简单逻辑,易于理解和实现
  2. ✅ 类视图提供更好的代码重用和组织
  3. ✅ 通用视图大大减少重复代码
  4. ✅ 装饰器和Mixin增强视图功能
  5. ✅ 完整的CRUD操作支持

合理选择视图类型能够提高开发效率和代码质量。

下一篇

我们将学习如何使用通用视图和自定义模板标签来构建更复杂的Web应用。

7.1 模板基础 →

目录

返回课程目录

Released under the Apache 2.0 License.