26.4 Django 视图层

2024-06-25_084108

1. 视图函数

视图函数是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的错误处理机制来实现这一点.
创建MyDjango项目, 创建index应用.
在Django的视图中创建一个简单的HTTP响应, 该响应返回当前日期和时间.
# MyDjango的urls.py
from django.contrib import admin
from django.urls import path, includeurlpatterns = [path('admin/', admin.site.urls),path('', include(('index.urls', 'index'), namespace='index'))
]

image-20240624125003389

# index的urls.py
from django.urls import path
from index.views import current_datetimeurlpatterns = [path('', current_datetime, name='current_datetime'),
]

image-20240624125038781

# index的views.py
from django.shortcuts import HttpResponse
import datetimedef 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)

image-20240624125106527

current_datetime视图函数接收一个request对象(它是Django的HTTPRequest对象的一个实例),
然后获取当前时间(now), 并构造一个HTML字符串(html), 其中包含当前时间.
最后, 返回了一个HttpResponse对象, 该对象包含了这个HTML字符串.
启动项目, 访问: 127.0.0.1:8000 , 查看页面, 内容如下.

image-20240624124917326

视图层, 熟练掌握两个对象即可: 请求对象(request)和响应对象(HttpResponse).

2024-06-24_122018

后续列出常用的一些请求对象和响应对象的成员(属性, 方法)不会立刻举例说明, 再后续学习中会频繁使用.

2. HttpRequest对象

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

2.1 HttpRequest属性

在Django中, HttpRequest对象被用来表示客户端发送的HTTP请求.
这个对象包含了请求行, 首部信息(headers)和内容主体(body)的详细信息, 并将它们封装成一系列属性.
大多数这些属性是只读的, 这意味着不应该尝试去修改它们, 因为它们反映了原始的HTTP请求.
以下是一些常用的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方法

以下是一些常用的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对象

在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(): 返回所有值, 但如果有重复的键, 则只返回与最后一个键对应的值.
标准的Python dict类型不允许一个键(key)对应多个值(value).
在Python字典中, 每个键都是唯一的, 并且只关联一个值.
如果你试图将一个已经存在的键与新的值关联, 那么该键的旧值将被新值替换.然而, 可以通过几种不同的方式在Python字典中存储多个值, 虽然这并不意味着一个键直接对应多个值, 但可以实现类似的效果:
将值设置为列表: 可以将一个键关联到一个容器对象, 这样该键就可以'存储'多个值. 例如: my_dict = {'key': [1, 2, 3]} .
Django的QueryDict对象是一种特殊的数据结构, 它扩展了字典的概念以允许一个键对应多个值.
这在处理HTTP请求参数时特别有用, 因为HTTP请求中的查询字符串和表单数据经常包含重复的键.
QueryDict提供了.getlist(key)方法, 该方法返回与给定键关联的所有值的列表, 而不是像标准字典那样只返回最后一个值.
示例: 假设有以下的查询字符串: ?a=1&a=2&b=3使用get方法: query_dict.get('a')将返回'2' (最后一个值).
使用getlist方法: query_dict.getlist('a')将返回['1', '2'] (所有值).
总结: QueryDict是Django中用于处理HTTP请求参数的一个特殊数据结构, 它允许键有多个值, 并提供了一些用于访问这些值的方法.
它是HttpRequest对象的GET和POST属性的类型, 因此开发者可以在视图中直接使用这些属性来访问和处理请求参数.

3. HttpResponse对象

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

3.1 常用响应对象

HttpResponse或其子类对象是用于构建和发送HTTP响应给客户端的主要方式.
以下是一些常用的HttpResponse或其子类对象:
* 1. HttpResponse: 基础响应对象.它接收一个字符串作为内容, 并可以指定状态码, 头部信息和字符集.示例: HttpResponse("Hello, world!")
* 2. JsonResponse: 用于返回JSON格式的响应.它接收一个字典或可序列化的对象, 并自动将其转换为JSON格式.实例: data = {'name': 'qq', 'age': 18}第一种方式:import jsonreturn HttpResponse(json.dumps(data1))第二种方式:from django.http import JsonResponsereturn 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 常用属性与方法

以下是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环境中使用.
在下面的示例中, 创建了一个简单的视图函数my_view, 
它返回一个包含文本"Hello, world!"的HttpResponse对象, 并设置了状态码, 内容类型和cookie.
# index的views.py
from django.http import HttpResponsedef 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

image-20240625001133275

# index的urls.py
from django.urls import path
from index.views import my_viewurlpatterns = [path('', my_view, name='my_view'),
]

image-20240625001106711

启动项目, 访问: 127.0.0.1:8000 .

image-20240625001010019

3.3 重定向说明

在HTTP协议中, 301302是两种不同的状态码, 分别对应永久重定向和临时重定向.301跳转表示'永久重定向', 这意味着请求的资源已被永久分配了新的URI, 即资源已经被永久地改变了位置.
这种情况下, 搜索引擎在抓取新内容的同时, 会将原本的旧网址用重定向之后的新网址替换.
301跳转对搜索引擎优化(SEO)是友好的, 因为它传递了页面的权重.302跳转表示'临时重定向', 这是指资源被临时改变位置并分配了新的URI.
301跳转不同, 302跳转不会传递页面的权重, 且搜索引擎会抓取新的内容但保留旧的网址.
302跳转通常用于短期的页面变动, 比如未登录用户访问个人中心时重定向到登录页面, 或者404页面提示后跳转到首页等.301302的共同点:
301302状态码都表示重定向, 浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址,
用户看到的效果就是他输入的地址A瞬间变成了另一个地址B. 这个地址可以从响应的Location首部中获取.301302的区别:
301表示旧地址A的资源已经被永久地移除了(这个资源不可访问了),
搜索引擎在抓取新内容的同时也将旧的网址交换为重定向之后的网址;302表示旧地址A的资源还在(仍然可以访问), 这个重定向只是临时地从旧地址A跳转到地址B,
搜索引擎会抓取新的内容而保存旧的网址.重定向原因:
* 1. 网站调整(如改变网页目录结构).
* 2. 网页被移到一个新地址.
* 3. 网页扩展名改变(如应用需要把.php改成.Html或.shtml).这种情况下, 如果不做重定向, 则用户收藏夹或搜索引擎数据库中旧地址只能让访问客户得到一个404页面错误信息, 访问流量白白丧失;
再者某些注册了多个域名的网站, 也需要通过重定向让访问这些域名的用户自动跳转到主站点等.

3.3 常用响应方式

在Django框架中, HttpResponse(), render(), 和redirect()是常用的函数和类, 用于构建HTTP响应并返回给客户端.
这些函数大大简化了在Django中构建HTTP响应的过程, 使得开发者可以更加关注于业务逻辑和视图逻辑的实现, 而不是底层的HTTP响应构建.
3.3.1 基础响应
HttpResponse(): 是Django中用于生成HTTP响应的基础类.
可以传递一个字符串作为响应的内容, 还可以设置其他的HTTP头部.
from django.http import HttpResponse  def my_view(request):  return HttpResponse("Hello, World!")
在这个例子中, 视图函数my_view返回了一个简单的字符串"Hello, World!"作为HTTP响应的内容.
3.3.2 返回渲染模板
render()函数是一个快捷方式, 用于渲染一个给定的模板, 并将一个上下文字典中的值作为模板变量传递给模板.
render函数会加载指定的模板, 用提供的上下文数据渲染它, 并返回一个HttpResponse对象, 该对象包含了渲染后的模板内容.函数格式:render(request, template_name[, context])
参数:
- request: 是一个HttpRequest对象, 它包含了客户端发送的所有信息, 如GET/POST参数, HTTP头部信息等.
- template_name: 是一个字符串, 指定了要渲染的模板文件的名称(不包含路径, 只包含模板文件名, Django会在模板加载器配置的目录中查找该文件).
- context: 是一个可选的字典, 包含了模板渲染时所需的所有变量和它们的值.这个字典中的每一个键值对都会作为一个变量传递给模板进行渲染.
# index的views.py
from django.shortcuts import render  def my_view(request):  context = {'greeting': 'Hello, World!'}  return render(request, 'my_template.html', context)
在模板中, 不需要(也不应该)引用context字典本身, 只需要直接引用字典中的键(即变量名).
<!-- templates的my_template.html -->
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>测试页面</title>
</head>
<body>
<p>{{ greeting }}</p>
</body>
</html>

在这个例子中, my_view视图函数使用render()函数来渲染名为'my_template.html'的模板,
并将一个包含greeting键的字典作为上下文传递给模板.
模板文件my_template.html中应该使用模板语法 {{ greeting }} 来显示这个值.
以下是Django中render()函数的源码, 地址: D:\Python\Python38\Lib\site-packages\django\shortcuts.py
# 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)
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 重定向快捷函数
redirect()函数: 用于生成一个HTTP重定向响应. 
它接受一个URL作为参数, 并返回一个HttpResponseRedirect对象, 这是HttpResponse的一个子类.
该对象告诉浏览器将用户临时重定向(302)到指定的URL.
* 注意: 在使用重定向时, 确保目标URL是正确的, 避免出现死循环或者跳转到错误的页面.
# index的urls.py
from django.urls import path
from index.views import my_view, homeurlpatterns = [path('', my_view, name='my_view'),path('home/', home, name='home'),
]
# index的views.py
from django.shortcuts import HttpResponse, redirectdef my_view(request):return redirect('/home/')  # URL硬编码, def home(request):return HttpResponse('home!')
在这个例子中, my_view视图函数在执行完一些逻辑后, 将用户重定向到'/home/'这个URL, 访问本站点根目下的home目录.

2024-06-25_014112

4. CBV和FBV

在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()方法来处理请求.
以下是一个简单的例子, 它演示了如何创建一个基于类的视图来处理用户的主页请求. 
首先, 需要定义一个继承自django.views.generic.base.View的视图类.
在这个类中, 可以定义处理不同HTTP请求方法的方法, 如get, post等.
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方法来生成响应, 这是一种简化的处理方式.
接下来, 需要在项目的URL配置文件中为上述视图类配置路由.
使用as_view()方法将视图类转换为可调用的视图函数, 并将其与URL模式关联起来.
from django.urls import path  
from .views import HomeView  urlpatterns = [  # ... 其他URL模式 ...  path('home/', HomeView.as_view(), name='home'),  
]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/34507.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Linux安装frp实现内网穿透

Linux运维工具-ywtool 目录 一. 简介二.代理类型三.frp支持的Linux的架构四.安装1.准备工作2.配置frp服务器端(a)下载安装包(b)解压安装包(c)修改配置文件(d)启动服务端 3.配置frp客户端(a)下载安装包并修改配置文件(b)启动客户端 4.测试连接 五.其他1.多端口穿透(a)服务端(b)客…

【AI】存储自定义色板库

点击左上角色板&#xff0c;弹出色板框&#xff1b; 色板框的左下角有一个“色板库” 菜单&#xff0c;点击色板库菜单&#xff0c;弹出色板库&#xff1b; 色板库弹窗的第一条数据【存储色板】&#xff0c;点击存储色板&#xff0c;出现自定义色板所在文件路径&#xff1b; 找…

计算机毕业设计Thinkphp/Laravel校园体育器材管理系统

校园体育器材管理系统在流畅性&#xff0c;续航能力&#xff0c;等方方面面都有着很大的优势。这就意味着校园体育器材管理系统的设计可以比其他系统更为出色的能力&#xff0c;可以更高效的完成最新的体育器材、器材借用、器材归还、器材损坏、采购入库、器材报废、维修记录等…

Spring Boot整合RocketMQ实现延迟消息消费

导包 <dependency><groupId>org.apache.rocketmq</groupId><artifactId>rocketmq-spring-boot-starter</artifactId><version>2.0.3</version></dependency>添加配置信息 application配置文件 # rocketMq地址 rocketmq.name…

Ubuntu+Apache2 搭建Gerrit 环境

一、前言 时隔多年&#xff0c;好久没有更新CSDN 博客了&#xff0c;主要原因有如下两点&#xff1a; 1、平时工作繁忙&#xff0c;无暇更新。 2、工作内容涉及信息安全&#xff0c;一些工作经验积累不便更新到互联网上。 最近一直在折腾搭建Gerrit 环境&#xff0c;最开始是…

基于Transformer的自监督学习在NLP中的前沿应用

1. 引言 自然语言处理&#xff08;NLP&#xff09;领域正经历一场由自监督学习&#xff08;Self-Supervised Learning, SSL&#xff09;和Transformer架构共同驱动的革命。自监督学习通过巧妙地利用未标注数据&#xff0c;大大减少了对人工标注的依赖&#xff0c;而Transforme…

基于IM948(Low-cost IMU+蓝牙)模块的高精度PDR(Pedestrian Dead Reckoning)定位系统 — 可以供模块和配套代码

一、背景与意义 行人PDR定位系统中的PDR&#xff08;Pedestrian Dead Reckoning&#xff0c;即行人航位推算&#xff09;背景意义在于其提供了一种在GPS信号不可用或不可靠的环境下&#xff0c;对行人进行精确定位和导航的解决方案。以下是关于PDR背景意义的详细描述&#xff1…

Shopee、Lazada测评,是找服务商呢?还是建议自己养号补单呢?

目前大部分Shopee、Lazada的卖家由于运营成本的增加&#xff0c;都会找服务商测评来打造权重&#xff0c;但是找服务商有很多不靠谱&#xff0c;建议还是自行精养一批号&#xff0c;账号在手里比较安全可控&#xff0c;随时随地可以送测&#xff0c;精准搜索关键词货比三家下单…

【日记】希望文竹长得越来越好吧(856 字)

正文 为什么昨天给老师提早说了今天上课…… 今天都要忙死了。不论上午下午都手忙脚乱。上午之前的存量客户来开新账户&#xff0c;流程卡在客户经理尽调那里。恰好那个客户经理还是部门主管&#xff0c;我们没一个人敢催。向副行长汇报情况&#xff0c;又跟客户说。客户跟他们…

【Android】android studio简单实现图书馆借阅管理系统

希望文章能给到你启发和灵感&#xff5e; 点赞收藏关注 支持一下吧&#xff5e; 阅读指南 序幕一、基础环境说明1.1 硬件环境1.2 软件环境 二、整体设计2.1 数据库逻辑处理&#xff1a;2.2 登录/注册模块2.3 功能界面初始化&#xff1a;2.4 图书管理模块2.5 图书租借服务2.6 读…

Java25年还有更多的工作岗位适合二本学生就业吗?

Java作为一种广泛使用的编程语言。尽管技术领域不断发展和变化&#xff0c;Java依然在许多行业中占据重要地位。以下是一些原因&#xff0c;刚好我有一些资料&#xff0c;是我根据网友给的问题精心整理了一份「JAVA的资料从专业入门到高级教程」&#xff0c; 点个关注在评论区…

基于Java的软件测试管理系统【附源码】

毕业&#xff08;设计&#xff09;论文 题 目&#xff1a; 软件测试管理系统 学 号&#xff1a; 姓 名&#xff1a; 院 部&#xff1a; 专 业&#xff1a; 班 级&#xff1a; 指导教师&#xff1a; 职 称&#xff1a; 完成日期&#xff1a; 年 月 日 摘要 随着信息技术的不断…

[leetcode]insert-into-a-binary-search-tree

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:TreeNode* insertIntoBST(TreeNode* root, int val) {if (root nullptr) {return new TreeNode(val);}TreeNode* pos root;while (pos ! nullptr) {if (val < pos->val) {if (pos->left nullptr…

如何从0构建一款类jest工具

Jest工作原理 Jest 是一个流行的 JavaScript 测试框架&#xff0c;特别适用于 React 项目&#xff0c;但它也可以用来测试任何 JavaScript 代码。Jest 能够执行用 JavaScript 编写的测试文件的原因在于其设计和内部工作原理。下面是 Jest 的工作原理及其内部机制的详细解释&…

NetSuite Account Merge 科目合并功能分析

最近项目中&#xff0c;客户有提到过能否将不用的Account与新建的Account进行合并&#xff0c;即我们所说的Merge功能&#xff5e;可以&#xff0c;但是该功能有使用的限制&#xff0c;比如最直接的一点需要注意&#xff0c;不同类型的Account是不可以使用Merge功能的&#xff…

汽车软件开发者的必修课:ASPICE 4.0主要特点、优势及与之前版本的变化之处

ASPICE&#xff08;汽车SPICE&#xff09;4.0是专为汽车行业量身定制的过程评估模型&#xff0c;旨在确保软件和系统开发过程的质量和可靠性。它是更广泛的 ISO/IEC 330xx 系列标准的一部分&#xff0c;源自通用 SPICE&#xff08;软件流程改进和能力确定&#xff09;框架。 AS…

批归一化(Batch Normalization)和层归一化(Layer Normalization)的作用

在深度学习领域&#xff0c;归一化技术被广泛用于加速神经网络的训练速度并提高其稳定性。本文将介绍两种常见的归一化方法&#xff1a;批归一化&#xff08;Batch Normalization, BN&#xff09;和层归一化&#xff08;Layer Normalization, LN&#xff09;&#xff0c;并通过…

ATA-7025高压放大器的优势如何

高压放大器是一类在电子领域中具有重要作用的设备&#xff0c;其主要功能是将输入信号的电压放大到更高的水平。在许多应用中&#xff0c;高压放大器展现出独特的优势&#xff0c;下面将介绍高压放大器的优势以及它们在不同领域的应用。 高压放大器的优势 1.信号驱动能力强 高压…

ATA-3040C功率放大器的基本要求包括什么

功率放大器是电子设备中常用的一个组件&#xff0c;用于将输入信号增强到足够大的电平&#xff0c;以驱动负载而不失真。要设计一个高效和性能优越的功率放大器&#xff0c;需要考虑多个基本要求和设计考虑因素。下面安泰电子将介绍功率放大器的基本要求&#xff0c;以及如何满…

中兴光猫破解telnet配置命令汇总

中兴光猫telnet配置命令汇总 | LogDicthttps://www.logdict.com/archives/zhong-xing-guang-mao-telnetpei-zhi-ming-ling-hui-zong