掘金 后端 ( ) • 2024-04-25 22:38

theme: smartblue

本文简介

点赞 + 关注 + 收藏 = 学会了

00.png

上一篇 《『Django』路由urls》 中介绍了 Django 路由的用法,当时提到路由和视图其实是密不可分的合作伙伴。路由有点像饭店的服务员,引导顾客到指定的饭桌,然后根据顾客需求向厨房下单,厨师经过一番处理后,把煮好的菜传给顾客吃。这个厨师就是本文要介绍的『视图』。

01.png

什么是视图?

Django 中,视图的全称应该叫『视图函数』,简称视图(Views)。从字面上理解视图就是 Python 函数,是处理用户请求并返回相应内容的核心组件。通常会在视图函数里返回 HTML 网页、JSON 类型的接口、重定向、404等。

视图函数一般写在各应用下的 views.py 文件里。

视图决定了 Web 应用的行为和响应。在 Django 中,主要有两种类型的视图:

  • FBV:基于函数的视图
  • CBV:基于类的视图

FBV(Function-Based Views)和CBV(Class-Based Views)是两种处理视图的方式。

要使用视图需要2步,第1步是先创建一个路由指向视图函数,第2步是创建视图函数。

FBV:函数视图

FBV(Function-Based Views)是基于函数的视图方式。它是一种简单直观的方式,使用Python 函数来处理 HTTP 请求并返回响应。在FBV中,每个视图都是一个独立的 Python 函数,接收 HTTP 请求对象作为参数,并返回 HTTP 响应对象。

其实我们在前面的文章 《『Django』路由urls》 里用的都是函数视图。

先创建一个路由:

# urls.py 项目的路由文件
from django.urls import path
from blog.views import blogIndex

urlpatterns = [
  path("blog/", blogIndex)
]

然后在 blog 这个应用里的 views.py 编写以下代码:

from django.http import HttpResponse

def blogIndex(request):
  return HttpResponse(f'这里是博客模块的首页')

项目运行起来后,在浏览器访问 http://127.0.0.1:8000/blog/

02.png

CBV:类视图

CBV(Class-Based Views)是基于类的视图方式。它使用 Python 类来组织和管理视图逻辑。在CBV中,每个视图通常是一个类方法,用于处理不同类型的 HTTP 请求。CBV提供了更多的灵活性和可扩展性,允许你在不同的方法中组织视图逻辑。

使用类视图的话,路由文件和视图文件的代码都会有所不同。

先配置一下路由:

# urls.py 项目的路由文件
from django.urls import path
from blog.views import blogIndex

urlpatterns = [
  path("blog/", blogIndex.as_view())
]

然后在 blog 这个应用里的 views.py 编写以下代码:

from django.http import HttpResponse
from django.views import View

class blogIndex(View):
  def get(self, request):
    return HttpResponse(f'雷猴,这里是博客模块的首页')

此时访问 http://127.0.0.1:8000/blog/ 会看到这个界面。

03.png

Django 中,当你使用类视图时,需要调用 as_view() 方法来将类视图转换为可调用的视图函数。这是因为 DjangoURL 路由系统需要将视图映射到 URL 模式,而类视图本身只是Python 类,无法直接作为视图函数使用。因此,需要使用 as_view() 方法将类视图转换为可调用的函数,以便在 URL 配置中使用。

在类视图中,需要确保你的类继承自 django.views.View 类或其子类,这样才能正确使用 as_view() 方法。django.views.View 类提供了一些基本的 HTTP 请求方法(如 GETPOST 等),你可以在子类中覆盖这些方法来处理不同类型的请求。

关于 GETPOST 这些请求方法稍后会讲到。

请求与响应(以GET和POST举例)

客户端和服务器通常使用HTTP的方式进行数据传递,客户端向服务器发起对话时,会创建一个“请求对象”,而服务器回复客户端时会创建一个“响应对象”。

对于前端来说,通常就是用浏览器向服务器发起请求,用的是 Ajax ,现在流行使用 axios 这个库发起请求。

Django 这边会通过视图函数接收前端发起的请求,这个“请求对象”里通常包含请求头、请求方法等信息,Django 会将这个请求对象打包成 HttpRequest 对象,并使用第一个参数(request) 来接收这个请求对象。

函数视图中,通过解析 request 这个参数可以获取到客户端发起的请求方法(通常是 GETPOST)。

先将项目的路由文件调整回函数视图的用法:

# urls.py 项目的路由文件
from django.urls import path
from blog.views import blogIndex

urlpatterns = [
  path("blog/", blogIndex)
]

然后调整一下 blog 应用的函数视图

# blog/views.py

from django.http import HttpResponse

def blogIndex(request):
  if request.method == 'GET':
    return HttpResponse('使用了GET请求')
  if request.method == 'POST':
    return HttpResponse('使用了POST请求')

此时借助 Postman 工具分别向 http://127.0.0.1:8000/blog/ 发起 GETPOST 请求

04.png

再看看 POST 请求。

05.png

默认情况下,使用 POSTPUTPATCHDELETE 都是会报 403 这个错误的,这是因为 Django 默认开启防止csrf(跨站点请求伪造)攻击,此时有几种方法可以应对。

【方法1】

将项目配置文件的 django.middleware.csrf.CsrfViewMiddleware 注视掉。

# settings.py

MIDDLEWARE = [
    "django.middleware.security.SecurityMiddleware",
    "django.contrib.sessions.middleware.SessionMiddleware",
    "django.middleware.common.CommonMiddleware",
    # "django.middleware.csrf.CsrfViewMiddleware",
    "django.contrib.auth.middleware.AuthenticationMiddleware",
    "django.contrib.messages.middleware.MessageMiddleware",
    "django.middleware.clickjacking.XFrameOptionsMiddleware",
]

MIDDLEWARE 里有一句 django.middleware.csrf.CsrfViewMiddleware ,将它注释掉再用 Postman 发起一次 POST 请求就有响应结果了。

06.png

【方法2】

方法1是全局配置,如果你只需要配置某个视图函数,可以给这个函数配置一个 csrf_exempt 装饰器。

# 找到指定的视图函数
# blog/views.py

from django.views.decorators.csrf import csrf_exempt

@csrf_exempt
def blogIndex(request):
  if request.method == 'GET':
    return HttpResponse('使用了GET请求')
  if request.method == 'POST':
    return HttpResponse('使用了POST请求')

前面演示的都是通过 函数视图 来处理请求和响应,其实用 类视图 处理会更方便。

还是前面的例子,首先需要配置一下路由,让它能解释类函数。

# urls.py 项目的路由文件
from django.urls import path
from blog.views import blogIndex

urlpatterns = [
  path("blog/", blogIndex.as_view())
]

接着在编写一下视图的代码

# blog/views.py

from django.http import HttpResponse
from django.views import View

class blogIndex(View):
  def get(self, request):
    return HttpResponse('雷猴,GET请求')
  def post(self, request):
    return HttpResponse('雷猴,POST请求')

使用 类视图 可以更直观的看出 GETPOST 的代码,减少 if...else... 这类判断的代码。

响应HTML模板

前面的例子都是响应一段字符串,这显然不能满足我们日常开发网站的需求。

Django 支持响应 HTML 页面给回客户端。

在视图里返回 HTML 内容即可。

# blog/views.py

from django.http import HttpResponse

def blogIndex(request):
  html = """
    <h2>这是博客首页</h2>
  """
  return HttpResponse(html)

07.png

但这样书写 HTML 代码很不灵活,我们通常会将 HTML 代码写在 .html 文件里,这种方式在 Django 中称为“模板”。

模版的功能比较多,很适合单独开一篇文章来讲解,下一篇我们再介绍模板。

响应JSON

在前后端分离的项目中,后端通常只会返回数据内容给前端,而不是返回一个页面。返回的数据通常是以 JSON 为主。

此时我们需要用到 JsonResponse 来帮忙。具体的操作还是放在视图里。

# blog/views.py

def blogIndex(request):
  res = {
    'title': '雷猴',
    'content': '这里是博客首页'
  }
  return JsonResponse(res)

此时用 Postman 发起请求会得到这段 JSON 数据。

08.png

出现乱码的这个问题可以将 json_dumps_params 设置为 False 来解决。

# blog/views.py

def blogIndex(request):
  res = {
    'title': '雷猴',
    'content': '这里是博客首页'
  }
  return JsonResponse(res, json_dumps_params={'ensure_ascii': False})

以上就是本文的全部内容,下一篇介绍 Django 的模板功能。

IMG_2952.GIF

点赞 + 关注 + 收藏 = 学会了