Django教程:视图介绍及使用

Django是一个非常流行的Python Web框架,它允许开发者轻松构建强大的Web应用程序。上一篇文章中,我们介绍了Python的模型,以及模型相关的使用方法。在本文中,我将详细介绍Django视图的概念和用法,并通过一些示例代码来增强我们对Djang视图的理解。

视图是 Django 中处理 HTTP 请求和生成 HTTP 响应的函数或方法。它们负责处理用户的请求,并返回相应的内容。要创建视图,你需要定义一个函数或方法,并将其绑定到URL。

1.定义视图

首先,在Django项目的根目录下创建一个名为views.py的文件。在这个文件中,我们将定义我们的视图。

python 复制代码
# 在views.py中引入必要的模块
from django.shortcuts import render
from django.http import HttpResponse
from bbs import Post
# Create your views here.

def hello(request):
    return HttpResponse("Hello, Django !")

def get_post(request, title):
    # 从数据库中获取用户数据
    post= Post.objects.get(title=title)
    # 将数据传递给模板,渲染页面
    return render(request, 'post.html', {'post': post})

上面的代码示例中,我们定义了两个视图函数。第一个函数 hello 接收一个 request 对象,并返回一个简单的 HttpResponse 响应,其中包含 "Hello, Django!" 的文本。

第二个视图函数 get_post 接收两个参数:request 对象和 title,它从数据库中查询到与title相对应的用户数据,并将其传递给名为 post.html 的模板文件进行渲染。

2. URL映射

接下来,我们需要在 urls.py 文件中将这些视图映射到相应的URL。

python 复制代码
from django.urls import path
from . import views

urlpatterns = [
    path('hello/', views.hello, name='hello'),
    path('post/<str:title>/', views.title, name='get_post'),
]

在上面的代码中,我们使用 path 函数将URL映射到相应的视图函数。第一个URL模式将 hello/ 映射到 hello 视图函数。第二个URL模式将 post/ 后面的 title 部分传递给 get_post 视图函数。

3. 视图装饰器

Django提供了一些常用的视图装饰器,可以用于添加额外的功能或进行授权验证。

python 复制代码
from django.contrib.auth.decorators import login_required

@login_required
def protected_view(request):
    return HttpResponse("This view requires authentication.")

对于装饰器,目前我们只需要有个大致的了解,知道有这么个东西就行,后续内容中,会详细讲解装饰器的应用场景。

4. 模板渲染

Django的模板引擎允许将动态数据注入到HTML模板中,并将其呈现给用户。首先 我们需要在的 bbs 目录里创建一个 templates 目录。根据约定优于配置的原则,Django 将会在这个目录里查找模板文件。为啥?还记得我们经常提到 settings.py文件吗?默认的设置文件设置了 DjangoTemplates 后端,并将 APP_DIRS 设置成了 True。这一选项将会让 DjangoTemplates 在每个 INSTALLED_APPS 文件夹中寻找 "templates" 子目录。

python 复制代码
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

在刚刚创建好的templates目录下,再创建一个post文件夹,用于存放我们的模板文件。

html 复制代码
<html>
<head>
    <title>内容列表</title>
</head>

<body>
    {% for post in posts %}
    <h2>{{ post.title }}</h2>
    <div>
        {{ post.content }}
    </div>
    {% endfor %}
</body>
</html>

views.py中我们的视图函数可以这么写,将我们查询得到的post对象传递给 post/index.html

python 复制代码
from django.shortcuts import render, get_object_or_404
from django.http import  HttpResponse, Http404
from bbs.models import Post

def get_posts(request):
    posts = Post.objects.all
    return render(request, 'post/index.html', { 'posts': posts })

通过模板渲染出的页面如图所示:

5.基于类的视图

Django 提供了适用于很多应用的基本视图类。所有视图继承自 View 类,它处理视图链接到 URLs,HTTP 方法调度和其他简单功能。RedirectView 用于 HTTP 重定向,TemplateView 扩展基类来使它能渲染模板。

python 复制代码
urlpattern = [
	path("bbs/about/", TemplateView.as_view(template_name="about.html")),
]

任何传递到 as_view() 的参数将覆盖在类上设置的属性。在这个例子中,我们在 TemplateView 上设置 template_name,用于渲染about.html模板。当然,我们也可以采用继承已存在的视图并覆盖子类里的属性,来提供新的值或方法。

6.404异常处理

对于404异常,我们可以通过以下代码来进行处理:

python 复制代码
def get_post_if_404(request, title):
    try:
        post = Post.objects.get(title = title)
    except Post.DoesNotExist:
        raise Http404("Post Not Exist")
    return render(request, 'post/detail.html', {'post': post})

Django提供了更方便的函数来帮助我们处理此类异常:

python 复制代码
# 便捷写法
def get_post_404(request, title):
    post = get_object_or_404(Post, title=title)
    return render(request , 'post/detail.html', {'post': post})

为什么我们使用辅助函数 get_object_or_404() 而不是自己捕获 ObjectDoesNotExist 异常呢?为什么模型 API 不直接抛出 ObjectDoesNotExist 而是抛出 Http404 呢?

因为这样做会增加模型层和视图层的耦合性。指导 Django 设计的最重要的思想之一就是要保证松散耦合。

7.视图测试

测试是软件开发中十分重要的一个过程,虽然测试并不能使得我们的程序性能更优秀或者更加完美。但是对于中大型软件来说,编写测试用例来进行自动化测试是十分重要的,如果不通过用例来执行测试,意味着我们讲花费大量的时间来验证程序的功能。

按照惯例,Django 应用的测试应该写在应用的 tests.py 文件里。测试系统会自动的在所有以 tests 开头的文件里寻找并执行测试代码。 对于视图测试,Django 提供了一个供测试使用的 Client 来模拟用户和视图层代码的交互。

python 复制代码
def save_post(title, content, pub_date):
    return Post.objects.create(title= title, content = content, pub_date = pub_date)

# Create your tests here.
from django.test import TestCase
from django.utils import timezone
from django.urls import reverse
import datetime
from bbs.models import Post


def save_post(title, content, pub_date):
    return Post.objects.create(title= title, content = content, pub_date = pub_date)

# Create your tests here.
class PostModelTests(TestCase): 
    def test_post_insert_with_future_pub_date(self):

        pub_date = timezone.now() + datetime.timedelta(days=-20)
        # future_post = Post(title = '测试Post', content='测试内容', pub_date=pub_date)
        # self.assertIs(future_post.pub_date_valid(), True)
        future_post = save_post(title = '测试Post', content='测试内容', pub_date=pub_date)
        # 测试路由是否可被访问
        url = reverse("post_detail", args=(future_post.title,))
        response = self.client.get(url)
        self.assertEqual(response.status_code, 200)

通过在命令行运行: python manage.py test bbs 来执行我们的测试用例。

8.总结

Django 视图是 Django 框架中非常重要的一个组成部分,它负责接收用户请求并返回相应的响应。在 Django 中,视图可以分为类视图和函数视图两种。类视图继承自 Django 的 View 类,并提供了一些常用的方法来处理请求和响应。函数视图则是一种简单的方式,它直接接收一个请求并返回一个响应。

除了类视图,Django 还提供了一些其他的视图类型,例如 TemplateView。TemplateView 可以渲染一个模板并将其作为响应返回。为了方便大家学习,我在Github上新建了一个仓库,用于存储文章中涉及的源代码,供大家参考。

总之,Django 视图是 Django 框架中非常重要的一部分,它提供了许多有用的方法来处理请求和响应,并且可以轻松地与 URL 映射和模板引擎等其他功能集成

相关推荐
㳺三才人子6 小时前
初探 Flask
后端·python·flask·html
星栈独行6 小时前
我在 Rust 全栈项目里用 JWT 做无状态认证
开发语言·后端·rust·前端框架·开源·github·web
Java爱好狂.6 小时前
Java程序员体系化学习路线(2026最新版)
java·后端·java面试·java架构师·java程序员·java八股文·java学习路线
陈随易7 小时前
Redis 8.8发布,一定要更新
前端·后端·程序员
装不满的克莱因瓶7 小时前
SpringBoot 如何将 lib 目录中jar包打包进最终的jar包里面
spring boot·后端·maven·jar·mvn
ltl8 小时前
Transformer 原论文实验结果:为什么 28.4 BLEU 足以改写路线图
后端
excel8 小时前
为什么我推荐使用 Termius:现代 SSH 工具的完整体验
前端·后端
卷毛的技术笔记9 小时前
Java后端硬核实战:用Spring AI Alibaba+Redis给LLM装上“超强记忆中枢”
java·人工智能·redis·后端·spring·ai·系统架构
IT_陈寒10 小时前
Java的Optional差点让我掉坑里,这几个坑你别踩
前端·人工智能·后端
子兮曰10 小时前
Harness 驾驭工程深度教程:从 AGENTS.md 到全链路 AI 编码基础设施
前端·后端·ai编程