26.4 Django 视图层

1. 视图函数

handlebars 复制代码
视图函数是Django框架中用于处理Web请求并返回Web响应的重要组件.
以下是对Django视图函数的详细解释:
* 1. 视图函数与URL的映射.
     为了让Django能够知道哪个URL对应哪个视图函数, 需要在应用的urls.py文件中定义URL模式.
     使用path或re_path函数来定义URL模式, 并将URL模式映射到相应的视图函数.
     这样, 当用户访问特定的URL时, Django就会调用对应的视图函数来处理请求.
* 2. 视图函数的基本结构.
     视图函数通常定义在Django应用的views.py文件中.
     这些函数接收一个HttpRequest对象作为参数, 这个对象包含了客户端发送的HTTP请求的所有信息(如请求头, 请求体, 请求方法等).
     视图函数返回一个HttpResponse对象或者HttpResponse的子类对象, 这个对象包含了要发送给客户端的HTTP响应.
* 3. 视图函数的参数.
     request: 视图函数必须接收的第一个参数是一个HttpRequest对象. 这个对象包含了客户端发送的HTTP请求的所有信息.
     可以使用request对象的方法来获取请求的各种数据, 如request.GET获取GET请求的参数, request.POST获取POST请求的参数等.
* 4. 视图函数的返回值.
     HttpResponse: 视图函数返回一个HttpResponse对象或者其子类对象. 这个对象包含了要发送给客户端的HTTP响应. 
     可以使用HttpResponse构造函数直接创建一个响应对象, 并指定响应的内容, 状态码,响应头等.
     快捷函数: Django提供了许多快捷函数来方便地创建HTTP响应, 如render, redirect等, 
     render函数用于渲染一个模板并返回一个包含渲染结果的HttpResponse对象, 而redirect函数用于生成一个重定向响应.
* 5. 视图函数的常见操作.
     与数据库交互: 视图函数可以使用Django的ORM(对象关系映射)来与数据库进行交互, 如查询, 插入, 更新, 删除数据等.
     处理表单数据: 当用户提交表单时, 视图函数可以接收表单数据并进行处理, 如验证表单数据的合法性, 保存表单数据到数据库等.
     渲染模板: 视图函数可以使用Django的模板引擎来渲染HTML模板, 并将数据传递给模板进行动态展示.
     重定向: 视图函数可以使用redirect函数来生成一个重定向响应, 将用户重定向到其他URL.
* 6. 视图函数的注意事项.
     安全性: 视图函数需要处理来自用户的输入, 因此要注意防止SQL注入, 跨站脚本攻击(XSS)等安全问题.
     使用Django的ORM和表单验证等机制可以帮助提高代码的安全性.
     性能优化: 对于需要处理大量数据或执行复杂操作的视图函数, 可以考虑使用缓存, 分页等技术来提高性能.
     错误处理: 视图函数应该能够处理可能出现的异常和错误, 并返回适当的错误响应. 可以使用Django的错误处理机制来实现这一点.
handlebars 复制代码
创建MyDjango项目, 创建index应用.
在Django的视图中创建一个简单的HTTP响应, 该响应返回当前日期和时间.
python 复制代码
# MyDjango的urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include(('index.urls', 'index'), namespace='index'))
]
python 复制代码
# index的urls.py
from django.urls import path
from index.views import current_datetime

urlpatterns = [
    path('', current_datetime, name='current_datetime'),
]
python 复制代码
# index的views.py
from django.shortcuts import HttpResponse
import datetime


def current_datetime(request):
    now = datetime.datetime.now()
    formatted_now = now.strftime('%Y-%m-%d %H:%M:%S')
    html = f"""
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>当前时间</title>
    </head>
    <body>
    <h2> 现在的时间为: {formatted_now}. </h2>
    </body>
    </html>
"""
    return HttpResponse(html)
handlebars 复制代码
current_datetime视图函数接收一个request对象(它是Django的HTTPRequest对象的一个实例),
然后获取当前时间(now), 并构造一个HTML字符串(html), 其中包含当前时间.
最后, 返回了一个HttpResponse对象, 该对象包含了这个HTML字符串.
handlebars 复制代码
启动项目, 访问: 127.0.0.1:8000 , 查看页面, 内容如下.
handlebars 复制代码
视图层, 熟练掌握两个对象即可: 请求对象(request)和响应对象(HttpResponse).
handlebars 复制代码
后续列出常用的一些请求对象和响应对象的成员(属性, 方法)不会立刻举例说明, 再后续学习中会频繁使用.

2. HttpRequest对象

handlebars 复制代码
在Django中, request通常是传递给视图函数(或称为视图方法)的第一个参数, 它代表了当前HTTP请求的HttpRequest对象.
这里的request是一个变量名, 而不是一个类型或类名, 但它引用的是HttpRequest类的一个实例.

2.1 HttpRequest属性

handlebars 复制代码
在Django中, HttpRequest对象被用来表示客户端发送的HTTP请求.
这个对象包含了请求行, 首部信息(headers)和内容主体(body)的详细信息, 并将它们封装成一系列属性.
大多数这些属性是只读的, 这意味着不应该尝试去修改它们, 因为它们反映了原始的HTTP请求.
handlebars 复制代码
以下是一些常用的HttpRequest属性:
* 1. HttpRequest.method: 这个属性表示了HTTP请求的方法(例如, GET, POST, PUT, DELETE等, !!大写!!).
     可以使用它来判断请求的类型, 并据此执行不同的操作.
* 2.  HttpRequest.path: 这个属性包含了请求的URL的路径部分(不包括域名, 查询字符串等).
      例如, 对于URL: http://example.com/myapp/mypage/?param=value, HttpRequest.path的值将是/myapp/mypage/.
* 3. HttpRequest.GET: 这是一个包含GET请求中所有参数的QueryDict对象.
     查询参数通常是从URL的查询字符串(?key=value&another_key=another_value 部分)中提取的.
* 4. HttpRequest.POST: 如果请求中包含表单数据(通常通过HTML表单的POST方法发送), 则这些数据将被封装成一个QueryDict对象.
     即使POST请求没有包含任何表单数据, request.POST仍然会是一个空的QueryDict对象.
     因此, 不应该使用 if request.POST 来检查使用的是否是POST方法; 应该使用 if request.method == "POST" .
   另外: 如果使用POST上传文件的话, 文件信息将包含在FILES属性中.
* 5. HttpRequest.body: 这个属性包含了HTTP请求的原始请求体(raw request body).
     它通常是一个字节字符串(byte string), 包含了POST请求的数据(如果有的话).
     注意, 在Django中, 更常见的做法是使用HttpRequest.POST和HttpRequest.FILES来处理表单数据和文件上传,
     因为Django已经解析了这些数据并使其更容易访问.
* 6. HttpRequest.encoding: 这个属性用于获取HTTP请求的编码方式.
     如果客户端没有明确指定编码方式, 那么encoding属性的值为None, 表示使用DEFAULT_CHARSET的设置, 默认为'utf-8'.
     如果客户端发送的数据不是'utf-8'编码, 需要手动设置HttpRequest.encoding的值.
* 7. HttpRequest.META" 这个属性是一个标准的Python字典, 包含了所有可用的HTTP头部信息, 以及一些其他的元数据.
     这些头部信息是由客户端发送的, 并被服务器接收.     
	 CONTENT_LENGTH ------ 请求的正文的长度(是一个字符串).
     CONTENT_TYPE ------ 请求的正文的MIME类型.
     HTTP_ACCEPT ------ 响应可接收的Content-Type.
     HTTP_ACCEPT_ENCODING ------ 响应可接收的编码.
     HTTP_ACCEPT_LANGUAGE ------ 响应可接收的语言.
     HTTP_HOST ------ 客服端发送的HTTP Host头部.
     HTTP_REFERER ------ Referring 页面.
     HTTP_USER_AGENT ------ 客户端的user-agent字符串.
     QUERY_STRING ------ 单个字符串形式的查询字符串(未解析过的形式).
     REMOTE_ADDR ------ 客户端的IP地址.
     REMOTE_HOST ------ 客户端的主机名.
     REMOTE_USER ------ 服务器认证后的用户.
     REQUEST_METHOD ------ 一个字符串, 例如"GET"或"POST".
     SERVER_NAME ------ 服务器的主机名.
     SERVER_PORT ------ 服务器的端口(是一个字符串).
     注意, 头部信息的键都是大写, 并且前缀为HTTP_, 除了某些特殊的元数据.
     例如: 一个叫做X-Bender的头部将转换成META中的HTTP_X_BENDER键.
* 8. HttpRequest.FILES: 这个属性是一个标准的Python字典, 包含了所有上传的文件.
     每个键是<input type="file" name="..." />标签中name属性的值,
     每个值是一个UploadedFile对象, 它包含了文件的所有信息, 如文件名, 文件类型, 文件内容等.
* 9. HttpRequest.COOKIES: 这个属性是一个标准的Python字典, 包含了所有的cookie. 键和值都是字符串.
     如果cookie中包含了非ASCII字符, 它们将会被解码为Unicode字符串.
* 10. HttpRequest.session: 这个属性是一个可读写的, 类似于字典的对象, 用于在多个请求之间存储和检索数据.
     这通常用于跟踪用户的会话信息, 如用户名, 权限, 偏好设置等.
     Django提供了一个中间件来处理会话数据, 需要在MIDDLEWARE设置中添加
     'django.contrib.sessions.middleware.SessionMiddleware'来使用会话(默认添加).
* 11. HttpRequest.user: 这个属性是一个User对象, 表示当前请求的用户.
      在Django的用户认证系统中, 这个对象用于跟踪用户的身份和权限.
      如果请求没有关联到任何用户(例如, 用户未登录), 则request.user将是一个AnonymousUser对象(匿名用户).
      为了使用HttpRequest.user, 需要在你的项目中启用Django的用户认证系统, 并在MIDDLEWARE设置中添加
      'django.contrib.auth.middleware.AuthenticationMiddleware'(默认添加).

2.2 HttpRequest方法

handlebars 复制代码
以下是一些常用的HttpRequest方法:
* 1. HttpRequest.get_full_path(): 用于返回请求的完整路径, 包括查询字符串(如果有的话).
     例如, 如果请求的URL是: "/music/bands/the_beatles/?print=true", 那么get_full_path()将返回这个字符串.
     需要注意的是, 这个方法返回的是完整的路径, 而不仅仅是path, 
     例如在"http://127.0.0.1:8001/order/?name=lqz&age=10"这个例子中, get_full_path()将返回"/order/?name=lqz&age=10".

* 2. HttpRequest.is_ajax()方法: 用于判断一个HTTP请求是否为Ajax请求. 
     从Django 3.0版本开始, 这个方法已经被移除了.
     取而代之的是HttpRequest.headers属性中的X-Requested-With字段来判断请求是否为Ajax请求.
     要判断一个HTTP请求是否为Ajax请求, 可以使用以下代码:

2.3 QueryDict对象

handlebars 复制代码
在Django中, QueryDict对象是一个类似于字典的定制数据结构, 用于处理HTTP请求中的查询参数(GET)和表单数据(POST).
QueryDict定义在django.http.QueryDict中, 是HttpRequest对象的GET和POST属性的类型.
它继承自Python的字典类, 但具有一些特殊的特性和方法, 
用于处理可能具有多个值的键(例如, 当同一个键在查询字符串或表单中多次出现时).

特性:
  - 键和值都是字符串: 与标准Python字典类似, 但键和值都是字符串类型。
  - 键值可以重复: 与标准Python字典不同, QueryDict允许一个键有多个值.
  - 处理URL编码数据: QueryDict能够解析和处理URL编码的数据.
方法:
  - get(key, default=None): 根据键获取值. 如果键有多个值, 则返回最后一个值. 如果键不存在, 则返回默认值.
  - getlist(key, default=[]): 根据键获取值, 以列表形式返回所有值. 如果键不存在, 则返回空列表或指定的默认值.
  - update(other_dict): 用另一个QueryDict或标准字典更新当前QueryDict. 注意, 此方法会追加内容, 而不是替换它们.
  - items(): 返回键和值的列表, 但如果有重复的键, 则只返回最后一个键对应的值.
  - values(): 返回所有值, 但如果有重复的键, 则只返回与最后一个键对应的值.
handlebars 复制代码
标准的Python dict类型不允许一个键(key)对应多个值(value).
在Python字典中, 每个键都是唯一的, 并且只关联一个值.
如果你试图将一个已经存在的键与新的值关联, 那么该键的旧值将被新值替换.

然而, 可以通过几种不同的方式在Python字典中存储多个值, 虽然这并不意味着一个键直接对应多个值, 但可以实现类似的效果:
将值设置为列表: 可以将一个键关联到一个容器对象, 这样该键就可以'存储'多个值. 例如: my_dict = {'key': [1, 2, 3]} .
handlebars 复制代码
Django的QueryDict对象是一种特殊的数据结构, 它扩展了字典的概念以允许一个键对应多个值.
这在处理HTTP请求参数时特别有用, 因为HTTP请求中的查询字符串和表单数据经常包含重复的键.
QueryDict提供了.getlist(key)方法, 该方法返回与给定键关联的所有值的列表, 而不是像标准字典那样只返回最后一个值.
handlebars 复制代码
示例: 假设有以下的查询字符串: ?a=1&a=2&b=3

使用get方法: query_dict.get('a')将返回'2' (最后一个值).
使用getlist方法: query_dict.getlist('a')将返回['1', '2'] (所有值).
handlebars 复制代码
总结: QueryDict是Django中用于处理HTTP请求参数的一个特殊数据结构, 它允许键有多个值, 并提供了一些用于访问这些值的方法.
它是HttpRequest对象的GET和POST属性的类型, 因此开发者可以在视图中直接使用这些属性来访问和处理请求参数.

3. HttpResponse对象

handlebars 复制代码
在Django中, HttpResponse对象用于表示一个HTTP响应.
当Django的视图函数处理完一个请求后, 它会返回一个HttpResponse对象, 
该对象包含了发送给客户端的所有信息, 比如响应的内容, 状态码, 头部信息等.

3.1 常用响应对象

handlebars 复制代码
HttpResponse或其子类对象是用于构建和发送HTTP响应给客户端的主要方式.
以下是一些常用的HttpResponse或其子类对象:
* 1. HttpResponse: 基础响应对象.
     它接收一个字符串作为内容, 并可以指定状态码, 头部信息和字符集.
     示例: HttpResponse("Hello, world!")
* 2. JsonResponse: 用于返回JSON格式的响应.
     它接收一个字典或可序列化的对象, 并自动将其转换为JSON格式.
     实例: data = {'name': 'qq', 'age': 18}
     第一种方式:
     import json
     return HttpResponse(json.dumps(data1))
     第二种方式:
     from django.http import JsonResponse
     return JsonResponse(data, safe=False)
     当safe=True(默认值)时, JsonResponse只接受字典作为第一个参数(即数据), 如果传入非字典对象会抛出一个TypeError.
     当safe=False时, JsonResponse允许传入任何JSON可序列化的Python对象(如列表, 字典, 元组, 字符串, 数字, None等).
* 3. HttpResponseRedirect和HttpResponsePermanentRedirect: 用于重定向用户到另一个URL.
     HttpResponseRedirect表示临时重定向(状态码302), 而HttpResponsePermanentRedirect表示永久重定向(状态码301).
     示例: HttpResponseRedirect('/new-url/')
* 4. StreamingHttpResponse: 用于处理大量数据或实时数据, 如文件流.
     它接收一个迭代器, 并分块将数据发送给客户端.
* 5. HttpResponseForbidden, HttpResponseNotFound等: 这些是HttpResponse的子类, 用于返回具有特定状态码的响应.
     它们分别对应于不同的HTTP状态码, 如403(禁止访问)和404(未找到).
     示例: HttpResponseNotFound("Page not found")
* 6. HttpResponseServerError: 表示服务器内部错误的响应对象(状态码500).
     示例: HttpResponseServerError("Internal Server Error")
* 7. HttpResponseBadRequest: 表示客户端发送的请求有错误的响应对象(状态码400).
     示例: HttpResponseBadRequest("Bad Request")
* 8. FileResponse: 用于发送文件作为HTTP响应.
     它接收一个文件对象或文件路径, 并可以指定内容类型和其他参数.
* 9. HttpResponseNotModified: 表示客户端缓存的版本仍然是最新的, 无需发送新数据的响应对象(状态码304).
     通常与条件GET请求(如带有If-None-Match或If-Modified-Since头部的请求)一起使用.

除了上述内置的响应对象外,你还可以根据需要自定义响应对象,继承自HttpResponse或其子类,并添加自定义的逻辑或属性。

3.2 常用属性与方法

handlebars 复制代码
以下是HttpResponse对象的一些常用方法和属性:

构造方法:
from django.http import HttpResponse    
response = HttpResponse("Hello, world!")

属性:
* 1. content: 响应的内容, 通常是一个字符串.
* 2. status_code: HTTP响应状态码, 默认为200.
* 3. headers: 一个类字典对象, 用于设置或获取响应的头部信息.
* 4. charset: 响应内容的字符集编码, 默认为'utf-8'.
* 5. reason_phrase: HTTP状态码对应的短语, 比如'OK', 'Not Found'等.

方法:
* 1. set_cookie(key, value='', ...): 设置cookie.
* 2. delete_cookie(key, path='/', domain=None): 删除cookie.
* 3. set_status(status_code): 设置响应的状态码.
* 4. set_content_type(value): 设置响应的内容类型(MIME类型, 用于描述文档、文件或字节流的性质和格式).
* 5. has_header(header_name): 检查响应是否包含某个头部信息.
* 6. setitem(header_name, value): 设置响应的头部信息(同response[header_name] = value).
* 7. delitem(header_name): 删除响应的头部信息(同del response[header_name]).
* 8. getitem(header_name): 获取响应的头部信息(同value = response[header_name]).
* 9. contains(header_name): 检查响应是否包含某个头部信息(同if header_name in response).
* 10. iter(): 使HttpResponse对象可迭代, 以便在WSGI环境中使用.
handlebars 复制代码
在下面的示例中, 创建了一个简单的视图函数my_view, 
它返回一个包含文本"Hello, world!"的HttpResponse对象, 并设置了状态码, 内容类型和cookie.
python 复制代码
# index的views.py
from django.http import HttpResponse


def my_view(request):
    response = HttpResponse("Hello, world!")
    response.status_code = 201  # 设置状态码为201  
    response['Content-Type'] = 'text/plain'  # 设置内容类型为纯文本  
    response.set_cookie('my_cookie', 'cookie_value')  # 设置cookie  
    return response
python 复制代码
# index的urls.py
from django.urls import path
from index.views import my_view

urlpatterns = [
    path('', my_view, name='my_view'),
]
handlebars 复制代码
启动项目, 访问: 127.0.0.1:8000 .

3.3 重定向说明

handlebars 复制代码
在HTTP协议中, 301和302是两种不同的状态码, 分别对应永久重定向和临时重定向.

301跳转表示'永久重定向', 这意味着请求的资源已被永久分配了新的URI, 即资源已经被永久地改变了位置.
这种情况下, 搜索引擎在抓取新内容的同时, 会将原本的旧网址用重定向之后的新网址替换.
301跳转对搜索引擎优化(SEO)是友好的, 因为它传递了页面的权重.

302跳转表示'临时重定向', 这是指资源被临时改变位置并分配了新的URI.
与301跳转不同, 302跳转不会传递页面的权重, 且搜索引擎会抓取新的内容但保留旧的网址.
302跳转通常用于短期的页面变动, 比如未登录用户访问个人中心时重定向到登录页面, 或者404页面提示后跳转到首页等.

301和302的共同点:
301和302状态码都表示重定向, 浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,
用户看到的效果就是他输入的地址A瞬间变成了另一个地址B. 这个地址可以从响应的Location首部中获取.

301和302的区别:
301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),
搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;

302表示旧地址A的资源还在(仍然可以访问), 这个重定向只是临时地从旧地址A跳转到地址B,
搜索引擎会抓取新的内容而保存旧的网址.
       
重定向原因:
* 1. 网站调整(如改变网页目录结构).
* 2. 网页被移到一个新地址.
* 3. 网页扩展名改变(如应用需要把.php改成.Html或.shtml).

这种情况下, 如果不做重定向, 则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息, 访问流量白白丧失;
再者某些注册了多个域名的网站, 也需要通过重定向让访问这些域名的用户自动跳转到主站点等.

3.3 常用响应方式

handlebars 复制代码
在Django框架中, HttpResponse(), render(), 和redirect()是常用的函数和类, 用于构建HTTP响应并返回给客户端.
这些函数大大简化了在Django中构建HTTP响应的过程, 使得开发者可以更加关注于业务逻辑和视图逻辑的实现, 而不是底层的HTTP响应构建.
3.3.1 基础响应
handlebars 复制代码
HttpResponse(): 是Django中用于生成HTTP响应的基础类.
可以传递一个字符串作为响应的内容, 还可以设置其他的HTTP头部.
python 复制代码
from django.http import HttpResponse  
 
def my_view(request):  
    return HttpResponse("Hello, World!")
handlebars 复制代码
在这个例子中, 视图函数my_view返回了一个简单的字符串"Hello, World!"作为HTTP响应的内容.
3.3.2 返回渲染模板
handlebars 复制代码
render()函数是一个快捷方式, 用于渲染一个给定的模板, 并将一个上下文字典中的值作为模板变量传递给模板.
render函数会加载指定的模板, 用提供的上下文数据渲染它, 并返回一个HttpResponse对象, 该对象包含了渲染后的模板内容.

函数格式:
  render(request, template_name[, context])
参数:
- request: 是一个HttpRequest对象, 它包含了客户端发送的所有信息, 如GET/POST参数, HTTP头部信息等.
- template_name: 是一个字符串, 指定了要渲染的模板文件的名称
  (不包含路径, 只包含模板文件名, Django会在模板加载器配置的目录中查找该文件).
- context: 是一个可选的字典, 包含了模板渲染时所需的所有变量和它们的值.
  这个字典中的每一个键值对都会作为一个变量传递给模板进行渲染.
python 复制代码
# index的views.py
from django.shortcuts import render  
 
def my_view(request):  
    context = {'greeting': 'Hello, World!'}  
    return render(request, 'my_template.html', context)
handlebars 复制代码
在模板中, 不需要(也不应该)引用context字典本身, 只需要直接引用字典中的键(即变量名).
html 复制代码
<!-- templates的my_template.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>测试页面</title>
</head>
<body>
<p>{{ greeting }}</p>
</body>
</html>
handlebars 复制代码
在这个例子中, my_view视图函数使用render()函数来渲染名为'my_template.html'的模板,
并将一个包含greeting键的字典作为上下文传递给模板.
模板文件my_template.html中应该使用模板语法 {{ greeting }} 来显示这个值.
handlebars 复制代码
以下是Django中render()函数的源码, 地址: D:\Python\Python38\Lib\site-packages\django\shortcuts.py
python 复制代码
# render()函数的源码
from django.http import HttpResponse  
from django.template import loader  
  
def render(request, template_name, context=None, content_type=None, status=None, using=None):  
    """  
    Return a HttpResponse whose content is filled with the result of calling  
    django.template.loader.render_to_string() with the passed arguments.  
    """  
    content = loader.render_to_string(template_name, context, request=request, using=using)  
    return HttpResponse(content, content_type=content_type, status=status)
handlebars 复制代码
render()函数做了以下几件事情:
* 1. 导入必要的模块: HttpResponse用于创建HTTP响应, loader用于加载和渲染模板.
* 2. 定义render()函数, 它接受请求对象, 模板名称, 上下文(可选), 内容类型(可选), 
     HTTP状态码(可选)和模板引擎名称(可选)作为参数.
* 3. 使用loader.render_to_string()函数来渲染模板.
      这个函数会将模板名称, 上下文, 请求对象和模板引擎名称作为参数, 并返回渲染后的字符串.
      创建一个HttpResponse对象, 将渲染后的字符串作为响应内容, 并设置可选的内容类型和状态码.
* 4. 返回HttpResponse对象. 该对象包含了渲染后的模板内容以及其他可选的HTTP头部信息.
     content: 这是由模板引擎渲染后的HTML内容.
     它通常是一个字符串, 包含了所有模板标签(如 {{ variable }} 或 {% tag %})被替换后的结果.
     content_type: 这个参数指定了HTTP响应的内容类型(MIME类型).
     例如, 对于HTML内容, 它通常是'text/html'. 如果你不提供这个参数,
     Django通常会根据响应的内容来猜测一个合适的内容类型, 但在某些情况下, 可能需要明确指定它.
     status: 这个参数允许你设置HTTP响应的状态码. 默认情况下, 它是200, 表示请求成功.
3.3.3 重定向快捷函数
handlebars 复制代码
redirect()函数: 用于生成一个HTTP重定向响应. 
它接受一个URL作为参数, 并返回一个HttpResponseRedirect对象, 这是HttpResponse的一个子类.
该对象告诉浏览器将用户临时重定向(302)到指定的URL.
* 注意: 在使用重定向时, 确保目标URL是正确的, 避免出现死循环或者跳转到错误的页面.
python 复制代码
# index的urls.py
from django.urls import path
from index.views import my_view, home

urlpatterns = [
    path('', my_view, name='my_view'),
    path('home/', home, name='home'),
]
python 复制代码
# index的views.py
from django.shortcuts import HttpResponse, redirect


def my_view(request):
    return redirect('/home/')  # URL硬编码, 


def home(request):
    return HttpResponse('home!')
handlebars 复制代码
在这个例子中, my_view视图函数在执行完一些逻辑后, 将用户重定向到'/home/'这个URL, 访问本站点根目下的home目录.

4. CBV和FBV

handlebars 复制代码
在Django中, 处理视图主要有两种方式:
* 1. 基于函数的视图(Function-Based Views, 简称FBV).
     FBV使用函数来定义视图, 函数接收一个HttpRequest对象作为参数, 并返回一个HttpResponse对象作为响应.
     在处理简单的视图时, FBV比较方便快捷.
     然而, 在处理复杂的逻辑时, FBV可能会显得冗长和混乱, 因为它需要在每个视图函数中重复编写相同的代码.
     FBV的代码复用性较差, 因为它无法像CBV那样通过继承和Mixin类来实现代码的复用.
* 2. 基于类的视图(Class-Based Views, 简称CBV).
     CBV使用类来定义视图, 类继承自Django提供的通用视图类(如django.views.generic.base.View),
     并通过继承和重写方法来定制视图的行为.
     相比于FBV, CBV更加灵活和可扩展.
     它允许开发者通过继承和重写类中的方法来处理不同的HTTP请求方法(如GET, POST等), 从而使代码更具可重用性.
     CBV还支持面向对象技术, 如mixins(多重继承), 可以将代码分解为可重用的组件.
     当一个请求到达与某个类视图关联的URL时, Django的URL解析器会调用该类的as_view()方法, 该方法返回一个可调用的函数.
     这个函数会创建一个类的实例, 初始化其属性, 并调用dispatch()方法来处理请求.
handlebars 复制代码
以下是一个简单的例子, 它演示了如何创建一个基于类的视图来处理用户的主页请求. 
首先, 需要定义一个继承自django.views.generic.base.View的视图类.
在这个类中, 可以定义处理不同HTTP请求方法的方法, 如get, post等.
python 复制代码
from django.views import View  
from django.shortcuts import render  
  
class HomeView(View):  
    def get(self, request, *args, **kwargs):  
        # 在这里编写处理GET请求的逻辑  
        # 例如, 从数据库获取数据或渲染模板  
        context = {'message': 'Welcome to the Home Page!'}  
        return render(request, 'home.html', context)  
  
    def post(self, request, *args, **kwargs):  
        # 在这里编写处理POST请求的逻辑  
        # 例如, 处理表单提交  
        # ...  
        # 这里为了简单起见, 我们只返回GET请求的响应 (不常见)
        return self.get(request, *args, **kwargs)  # 调用了同一个类中的get方法来生成响应, 这是一种简化的处理方式.
    
handlebars 复制代码
接下来, 需要在项目的URL配置文件中为上述视图类配置路由.
使用as_view()方法将视图类转换为可调用的视图函数, 并将其与URL模式关联起来.
python 复制代码
from django.urls import path  
from .views import HomeView  
  
urlpatterns = [  
    # ... 其他URL模式 ...  
    path('home/', HomeView.as_view(), name='home'),  
]
相关推荐
coberup3 小时前
django Forbidden (403)错误解决方法
python·django·403错误
过期动态18 小时前
详解Python面向对象程序设计
开发语言·python·pycharm·django
阿乾之铭19 小时前
通过Django 与 PostgreSQL 进行WEB开发详细流程
python·postgresql·django
春天的菠菜20 小时前
【django】Django REST Framework (DRF) 项目中实现 JWT
后端·python·django·jwt
千里码aicood1 天前
[含文档+PPT+源码等]精品基于Python实现的django房屋出租系统的设计与实现
开发语言·python·django
啧不应该啊1 天前
Django替换现有用户模型(auth_user)
后端·python·django
大霸王龙1 天前
django+postgresql
数据库·后端·python·postgresql·django
hai405872 天前
基于python主观题自动阅卷系统毕业设计项目
spring boot·python·jmeter·django·make与makefile
零七点072 天前
Django遍历文件夹及文件
后端·python·django
是个热心市民2 天前
构建一个导航栏web
前端·javascript·python·django·html