Django视图详解

前言

欢迎来到我的博客

个人主页:北岭敲键盘的荒漠猫-CSDN博客


一、Django视图是什么?

视图(View) 是Django处理HTTP请求的核心组件。它接收一个HttpRequest对象,处理业务逻辑,并返回一个HttpResponse对象(如网页、JSON数据、重定向等)。

1. 视图的两种写法
  • 函数视图(FBV,Function-Based Views) :用Python函数实现。

    python 复制代码
    from django.http import HttpResponse
    
    def hello(request):
        return HttpResponse("Hello World!")
  • 类视图(CBV,Class-Based Views) :用类的方法处理请求(更结构化,适合复用)。

    python 复制代码
    from django.views import View
    from django.http import HttpResponse
    
    class HelloView(View):
        def get(self, request):
            return HttpResponse("GET请求示例")
        
        def post(self, request):
            return HttpResponse("POST请求示例")

二、编写第一个视图:详细步骤

1. 创建视图函数

views.py中定义一个处理请求的函数:

python 复制代码
# myapp/views.py
from django.http import HttpResponse

def home_page(request):
    return HttpResponse("<h1>欢迎来到我的网站!</h1>")
2. 配置URL路由

urls.py中将URL路径映射到视图:

python 复制代码
# myproject/urls.py
from django.urls import path
from myapp import views

urlpatterns = [
    path('', views.home_page, name='home'),  # 根路径指向home_page视图
]
3. 运行开发服务器
复制代码
python manage.py runserver

访问 [http://127.0.0.1:8000](http://127.0.0.1:8000) 即可看到页面。


三、深入理解请求(HttpRequest)和响应(HttpResponse)

1. HttpRequest对象:包含请求的所有信息
  • 常用属性

    • request.method:请求方法(GET、POST等)
    • request.GET:GET请求的参数(字典形式)
    • request.POST:POST请求的表单数据
    • request.FILES:上传的文件
    • request.user:当前登录用户(需启用认证中间件)
  • 示例:处理GET请求参数

    python 复制代码
    def greet(request):
        name = request.GET.get('name', '游客')  # 获取name参数,默认值'游客'
        return HttpResponse(f"你好,{name}!")
2. HttpResponse对象:返回内容给浏览器
  • 常见用法

    • 返回文本:HttpResponse("文本内容")
    • 返回HTML:HttpResponse("<h1>标题</h1>")
    • 返回JSON:JsonResponse({'data': 'xxx'})
    • 重定向:HttpResponseRedirect('/new-url/')
  • 示例:返回JSON数据

    python 复制代码
    from django.http import JsonResponse
    
    def json_example(request):
        data = {'status': 'success', 'message': '请求成功'}
        return JsonResponse(data)

四、函数视图(FBV)的完整流程

1. 处理GET和POST请求
python 复制代码
def contact(request):
    if request.method == 'POST':
        # 处理表单提交
        name = request.POST.get('name')
        email = request.POST.get('email')
        print(f"收到来自{name} ({email}) 的消息")
        return HttpResponseRedirect('/thanks/')  # 重定向到感谢页面
    else:
        # 显示空表单
        return render(request, 'contact.html')
2. 渲染模板(Template)

使用render()函数将数据传递到HTML模板:

python 复制代码
from django.shortcuts import render

def article_list(request):
    articles = Article.objects.all()  # 假设Article是模型
    return render(request, 'articles/list.html', {'articles': articles})

模板文件 articles/list.html

复制代码
{% for article in articles %}
    <h2>{{ article.title }}</h2>
    <p>{{ article.content }}</p>
{% endfor %}

五、类视图(CBV)的用法详解

1. 基本结构
python 复制代码
from django.views import View
from django.http import HttpResponse

class MyView(View):
    def get(self, request):
        # 处理GET请求
        return HttpResponse("GET请求")

    def post(self, request):
        # 处理POST请求
        return HttpResponse("POST请求")
2. 在URL中使用类视图
python 复制代码
# urls.py
urlpatterns = [
    path('myview/', MyView.as_view(), name='my-view'),
]
3. 类视图的优势:复用与扩展
  • 继承内置通用视图 (如ListView, DetailView

  • 重写方法 自定义行为:

    python 复制代码
    class ArticleListView(ListView):
        model = Article  # 关联模型
        template_name = 'articles/list.html'  # 指定模板
        context_object_name = 'article_list'  # 模板中使用的变量名
    
        def get_queryset(self):
            # 过滤已发布的文章
            return Article.objects.filter(status='published')

六、通用视图(Generic Views)快速入门

Django内置了处理常见场景的类视图,极大简化代码。

概念:

通用视图(Generic Views)是Django为解决Web开发中重复模式设计的"快捷工具包",它能让你用极简代码实现以下常见功能:

  • 显示对象列表(如商品列表、文章列表)
  • 展示单个对象详情(如用户详情页)
  • 处理表单创建/修改对象(如新建订单)
  • 日期归档页面(如按月份展示文章)
  • 删除对象前的确认操作

传统函数视图需要手动处理数据库查询、模板渲染等细节,而通用视图通过"约定优于配置"原则自动完成这些基础工作

1. ListView:显示对象列表
python 复制代码
from django.views.generic import ListView

class BookListView(ListView):
    model = Book  # 自动获取所有Book对象
    template_name = 'books/book_list.html'  # 默认模板:books/book_list.html
    context_object_name = 'books'  # 模板中变量名(默认object_list)
2. DetailView:显示单个对象详情
python 复制代码
from django.views.generic import DetailView

class BookDetailView(DetailView):
    model = Book
    # 默认模板:books/book_detail.html
    # 通过URL中的pk或slug获取对象(如 /books/1/)
3. 表单处理:CreateView/UpdateView
python 复制代码
from django.views.generic.edit import CreateView
from django.urls import reverse_lazy

class BookCreateView(CreateView):
    model = Book
    fields = ['title', 'author', 'price']  # 表单字段
    template_name = 'books/book_form.html'
    success_url = reverse_lazy('book-list')  # 提交成功后跳转的URL

七、实际场景案例

1. 用户登录视图
python 复制代码
from django.contrib.auth import authenticate, login
from django.shortcuts import render, redirect

def login_view(request):
    if request.method == 'POST':
        username = request.POST['username']
        password = request.POST['password']
        user = authenticate(request, username=username, password=password)
        if user is not None:
            login(request, user)
            return redirect('home')
        else:
            return render(request, 'login.html', {'error': '用户名或密码错误'})
    return render(request, 'login.html')
2. 文件上传
python 复制代码
def upload_file(request):
    if request.method == 'POST' and request.FILES['file']:
        uploaded_file = request.FILES['file']
        # 保存文件到服务器
        with open(f'uploads/{uploaded_file.name}', 'wb+') as destination:
            for chunk in uploaded_file.chunks():
                destination.write(chunk)
        return HttpResponse("文件上传成功!")
    return render(request, 'upload.html')

八、常见问题与调试技巧

1. 404错误处理
  • 使用get_object_or_404替代get

    python 复制代码
    from django.shortcuts import get_object_or_404
    
    def book_detail(request, pk):
        book = get_object_or_404(Book, pk=pk)
        return render(request, 'books/detail.html', {'book': book})
2. 调试视图
  • 打印请求信息

    python 复制代码
    def debug_view(request):
        print("请求方法:", request.method)
        print("GET参数:", request.GET)
        print("用户:", request.user)
        return HttpResponse("查看控制台输出")
3. 单元测试
python 复制代码
from django.test import TestCase, Client

class ViewTests(TestCase):
    def test_home_page(self):
        client = Client()
        response = client.get('/')
        self.assertEqual(response.status_code, 200)
        self.assertContains(response, "欢迎")

九、最佳实践总结

  1. 选择合适的视图类型

    • 简单逻辑用函数视图(FBV)
    • 复杂或重复逻辑用类视图(CBV)
  2. 保持视图简洁

    • 业务逻辑抽离到单独模块(如utils.py
    • 使用通用视图减少重复代码
  3. 安全注意事项

    • 始终验证用户输入
    • 使用@login_required限制敏感操作
    • 启用CSRF保护(表单中加{% csrf_token %}
  4. 性能优化

    • 使用select_relatedprefetch_related优化数据库查询
    • 缓存频繁访问的视图(如使用@cache_page装饰器)

相关推荐
gongzairen11 分钟前
Ngrok 内网穿透实现Django+Vue部署
后端·python·django
小小毛桃19 分钟前
在PyTorch中,使用不同模型的参数进行模型预热
人工智能·pytorch·python
cliffordl27 分钟前
ReportLab 导出 PDF(图文表格)
python·pdf
杰瑞学AI36 分钟前
LeetCode详解之如何一步步优化到最佳解法:27. 移除元素
数据结构·python·算法·leetcode·面试·职场和发展
前端开发张小七1 小时前
每日一练:3统计数组中相等且可以被整除的数对
前端·python
程序员总部1 小时前
Python正则表达式有哪些常用匹配字符?
python·mysql·正则表达式
天天进步20151 小时前
Python项目--基于Python的自然语言处理文本摘要系统
开发语言·python·自然语言处理
只会AI搜索得coder1 小时前
sqlite3 sqlcipher加密,解密,集成springboot,读取sqlcipher加密工具
java·spring boot·sqlite
匹马夕阳1 小时前
(二十二)安卓开发中的数据存储之SQLite简单使用
android·数据库·sqlite
小麦果汁吨吨吨1 小时前
Flask快速入门
后端·python·flask