Django - 视图函数

视图函数,或简称视图,是一种接受 Web 请求并返回 Web 响应的 Python 函数。 这个响应可以是网页的 HTML 内容,也可以是重定向,也可以是 404 错误,也可以是 XML 文档,也可以是图像. . . 或任何东西,真的。 视图本身包含返回该响应所需的任意逻辑。 此代码可以位于您想要的任何位置,只要它在您的 Python 路径上即可。 没有其他要求 —— 没有 “魔法”,可以这么说。 为了将代码放在某个地方,约定是将视图放在一个名为 views.py 的文件中,该文件位于您的项目或应用程序目录中。

简单示例

这里是一个以 HTML 文档形式返回当前日期和时间的视图:

1
2
3
4
5
6
7
from django.http import HttpResponse
import datetime

def current_datetime(request):
now = datetime.datetime.now()
html = "<html><body>It is now %s.</body></html>" % now
return HttpResponse(html)
  • 首先,我们从 django.http 模块导入类 HttpResponse ,以及 Python 的 datetime 库。
  • 然后,我们定义一个名为 current_datetime 的函数。这是一个视图函数。每个视图函数都将 HttpRequest 对象作为第一个参数,通常名为 request
    • 注意:视图函数名称无关紧要;它不需要以特定的名称来让 Django 识别它。我们在这里命名 current_datetime ,因为这个名字可以清楚的表示它的用途。
  • 视图返回一个包含生成的响应的 HttpResponse 对象。每个视图函数都要返回 HttpResponse 对象。(有例外,我们稍后再讲)
  • 属相

    • scheme

      代表请求协议的字符串(通常是 httphttps)。

    • path

      表示请求页面的完整路径的字符串,不包括方案、域或查询字符串。

    • method

      代表请求中使用的 HTTP 方法的字符串。保证是大写字母。

    • GET

      一个类似字典的对象,包含所有给定的 HTTP GET 参数。参见下面的 QueryDict 文档。

    • POST

      一个类似字典的对象,包含所有给定的 HTTP POST 参数,前提是请求包含表单数据。参见下面的 QueryDict 文档。如果你需要访问请求中发布的原始或非表单数据,可以通过 HttpRequest.body 属性来访问。

    • COOKIES

      一个包含所有 cookies 的字典。键和值是字符串。

    • FILES

      • 一个类似字典的对象,包含所有上传的文件。FILES 中的每个键是 <input type="file" name=""> 中的 nameFILES 中的每个值是一个 UploadedFile。更多信息请参见 管理文件
      • FILES 只有在请求方法是 POST,并且发布请求的 <form>enctype="multipart/form-data" 的情况下,才会包含数据。否则,FILES 将是一个类似字典的空白对象。
    • META

      一个包含所有可用的 HTTP 头文件的字典。可用的头信息取决于客户端和服务器,部分示例:

      • CONTENT_LENGTH —— 请求体的长度(字符串)。
      • CONTENT_TYPE —— 请求体的 MIME 类型。
      • HTTP_ACCEPT —— 可接受的响应内容类型。
      • HTTP_ACCEPT_ENCODING —— 可接受的响应编码。
      • HTTP_ACCEPT_LANGUAGE —— 可接受的响应语言。
      • HTTP_HOST —— 客户端发送的 HTTP 主机头。
      • HTTP_REFERER —— referrer 页面,如果有的话。
      • HTTP_USER_AGENT —— 客户端的用户代理字符串。
      • QUERY_STRING —— 查询字符串,是一个单一的(未解析的)字符串。
      • REMOTE_ADDR —— 客户机的 IP 地址。
      • REMOTE_HOST —— 客户机的主机名。
      • REMOTE_USER -- The user authenticated by the web server, if any.
      • REQUEST_METHOD —— "GET""POST" 等字符串。
      • SERVER_NAME —— 服务器的主机名。
      • SERVER_PORT —— 服务器的端口(字符串)。
    • headers

      一个不区分大小写的类似字典的对象,提供对请求中所有 HTTP 前缀头的访问(加上 Content-LengthContent-Type)。

  • 方法

    • get_host()

      使用 HTTP_X_FORWARDED_HOST (如果 USE_X_FORWARDED_HOST 已启用)和 HTTP_HOST 头信息,按顺序返回请求的发起主机。如果它们没有提供一个值,则该方法使用 SERVER_NAMESERVER_PORT 的组合,详见 PEP 3333

    • get_port()

      使用 HTTP_X_FORWARDED_PORT (如果 USE_X_FORWARDED_PORT 已启用)和 SERVER_PORT META 变量中的信息,按顺序返回请求的起始端口。

    • is_ajax()

      • 是否是 ajax 请求,该方法于 Django 3.1 中已被 废弃,因为它依赖于 jQuery 特定的方式来表示 AJAX 调用,而当前的用法倾向于使用 JavaScript Fetch API 。根据你的用例,你可以写你自己的 AJAX 检测方法,或者使用新的 HttpRequest.accepts() 方法,如果你的代码依赖于客户端 Accept HTTP 头。
      • 如果你正在编写自己的 AJAX 检测方法,request.is_ajax() 可以完全复制为 request.headers.get('x-requested-with') == 'XMLHttpRequest'
    • accepts(mime_type)

      如果请求的 Accept 头符合 mime_type 参数,则返回 True

      1
      2
      >>> request.accepts('text/html')
      True
  • 示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from django.http import HttpResponse

    def index(request):
    print(request.path)
    print(request.method)
    # print(request.is_ajax())
    print(request.accepts('text/html'))
    print(request.scheme)
    print(request.GET)
    print(request.POST)
    print(request.FILES)
    print(request.get_host())
    print(request.META.get('REMOTE_ADDR'))
    return HttpResponse('<h1>商品首页面</h1>')
  • 概述

  • render()

    • 概述

      • 将给定的模板与给定的上下文字典组合在一起,并以渲染的文本返回一个 HttpResponse 对象。
      • Django 没有提供返回 TemplateResponse 的便捷函数,因为 TemplateResponse 的构造函数提供了与 render() 同等程度的便利。
    • 参数

      • 必选参数
        • request
          用于生成此响应的请求对象。
        • template_name
          要使用的模板的全名或模板名称的序列。如果给定一个序列,则将使用存在的第一个模板。有关如何查找模板的更多信息,请参见 模板加载文档
      • 可选参数
        • context
          要添加到模板上下文的值的字典。 默认情况下,这是一个空的字典。 如果字典中的值是可调用的,则视图将在渲染模板之前调用它。
        • content_type
          用于结果文档的 MIME 类型。默认 'text/html'
        • status
          响应的状态码默认为 200
        • using
          用于加载模板的模板引擎的 NAME
    • 示例

      1
      2
      3
      4
      from django.shortcuts import render

      def show_goods1(request):
      return render(request, 'goods/goods.html')
  • redirect()

    • 概述

      • 返回一个 HttpResponseRedirect,指向传递参数的适当 URL。
      • 参数可以是:
        • 一个模型:模型的 get_absolute_url() 函数将被调用。
        • 视图名,可能带有的参数:reverse() 将被用于反向解析名称。
        • 一个绝对或相对 URL,将按原样用作重定向位置。
    • 示例

      1. 传递对象,对象的 get_absolute_url() 方法将被调用来指向重定向地址

        1
        2
        3
        4
        5
        6
        from django.shortcuts import redirect

        def my_view(request):
        ...
        obj = MyModel.objects.get(...)
        return redirect(obj)
      2. 传递视图名和一些可选的位置或关键字参数;URL 将使用 reverse() 方法来反向解析

        1
        2
        3
        4
        5
        6
        7
        8
        def my_view(request):
        ...
        return redirect('some-view-name', foo='bar')

        def login(request):
        ...
        return redirect(reverse('user:show'))
        return redirect('user:show')
      3. 传递绝对或相对 URL 来重定向

        1
        2
        3
        4
        5
        6
        7
        8
        9
        # 传递相对URL
        def my_view(request):
        ...
        return redirect('/some/url/')

        # 传递绝对URL
        def my_view(request):
        ...
        return redirect('https://example.com/')
    • 默认情况下,redirect() 返回临时重定向。所有以上形式都接受 permanent 参数;如果设置为 True 会返回一个永久重定向:

      1
      2
      3
      4
      def my_view(request):
      ...
      obj = MyModel.objects.get(...)
      return redirect(obj, permanent=True)
  • reverse()

    1. 在主路由上添加 namespace

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      # urls.py

      from django.contrib import admin
      from django.urls import path, include

      urlpatterns = [
      path("admin/", admin.site.urls),
      path("user/", include("user.urls", namespace="suer")),
      ]

    2. 在子路由上添加 name

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      # user/urls.py

      from django.urls import path

      from user.views import *

      # 注意:主路由上添加完namespace后会报错,需要在每个子路由中添加app_name
      app_name = "user"
      urlpatterns = [
      path("login/", login, name="login"),
      path("show/", show, name="show"),
      ]

    3. 使用 reverse

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      # user/views.py

      from django.shortcuts import render, redirect
      from django.urls import reverse

      # Create your views here.
      def login(request):
      if request.method == 'POST':
      return redirect(reverse('user:show'))
      # 直接用redirect重定向亦可
      return redirect('user:show')
      return render(request, 'user/login.html')


      def show(request):
      users = User.objects.all()
      return render(request, 'user/show.html', {'users': users})

------------- 本文结束 感谢您的阅读 -------------
正在加载今日诗词....