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.rhkb.cn/news/361127.html

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

相关文章

线稿一键转真人,comfyui工作流分享!

大家好&#xff01;我是极客菌 在数字艺术和图像处理的新时代&#xff0c;技术的进步不断拓宽着创意的边界。ComfyUI 提供了一套高效、易用的工作流&#xff0c;通过简单的节点操作即可实现从线稿到真人图像的转换。 这一技术不仅简化了创作流程&#xff0c;还极大地提升了图像…

深入解读一下 `com.google.android.material.appbar.CollapsingToolbarLayout`

简介 在现代 Android 应用中&#xff0c;提供流畅且美观的用户体验是非常重要的。CollapsingToolbarLayout 是 AndroidX库中 Material Components 的一部分&#xff0c;它提供了一种易于实现的可折叠工具栏效果&#xff0c;常用于提供视觉吸引力的标题栏和动画效果。 本文将详…

避开常见的坑,快速制作一个免费、交互式景区导游地图

目录 1 前言 2 注册登录 3 增加景区&#xff0c;注意设置地图中心点和级别 3.1 确定地图位置和缩放级别 3.2 新增景区&#xff0c;输入几个文本项目 3.3 可以继续调整地图位置和级别 4 增加景点 4.1 点击景点跳转错误 5 新增景区和景点介绍帖子&#xff0c;需要催一下…

【PyTorch】【机器学习】图片张量、通道分解合成和裁剪

一、导入所需库 from PIL import Image import torch import numpy as np import matplotlib.pyplot as plt二、读取图片 pic np.array(Image.open(venice-boat.jpg))上述代码解释&#xff1a;先用Image.open()方法读取jpg格式图片&#xff0c;再用np.array()方法将图片转成…

各大广告商竞相厮杀下,诞生了一个偏门的副业方式

前段时间&#xff0c;想买摩托车&#xff0c;但是媳妇不让买&#xff0c;所以我打算偷偷买&#xff0c;然后萌生了去摆摊赚钱的想法&#xff0c;但是还没有实施就在网上接触到了“某赚”APP&#xff0c;于是一发不可收拾&#xff0c;用我的话来说&#xff0c;我做的不是副业&am…

Map-JAVA面试常问

1.HashMap底层实现 底层实现在jdk1.7和jdk1.8是不一样的 jdk1.7采用数组加链表的方式实现 jdk1.8采用数组加链表或者红黑树实现 HashMap中每个元素称之为一个哈希桶(bucket),哈希桶包含的内容有以下4项 hash值&#xff08;哈希函数计算出来的值&#xff09; Key value next(…

超简单的nodejs使用log4js保存日志到本地(可直接复制使用)

引入依赖 npm install log4js 新建配置文件logUtil.js const log4js require(log4js);// 日志配置 log4js.configure({appenders: {// 控制台输出consoleAppender: { type: console },// 文件输出fileAppender: {type: dateFile,filename: ./logs/default, //日志文件的存…

.NET C# 使用GDAL将mdb转换gdb数据

.NET C# 使用GDAL将mdb转换gdb数据 目录 .NET C# 使用GDAL将mdb转换gdb数据1 环境2 Nuget3 Code 1 环境 VisualStudio2022 .NET6 GDAL 3.8.5 2 Nuget 3 Code FeatureExtension.cs public static class FeatureExtension {[DllImport("gdal.dll", EntryPoint &…

中文+Midjourney,能描画出什么样的作品呢?保姆级上手指南送给你

中文Midjourney&#xff0c;能描画出什么样的作品呢&#xff1f; 中文版Midjourney来了&#xff01; 没有一点预热&#xff0c;Midjourney中文版&#xff08;以下简称 MJCN&#xff09;在本周开放了两次内测邀请&#xff0c;只需用 QQ 扫描邀请码&#xff0c;就可以在 QQ 频道…

VB列表框

移动是将列表框1中选中的数字移动到列表框2中。 全部是将列表框1中所有数字移动到列表框2中。 Public Class Form1Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.LoadDim i As Integer, a As IntegerRandomize()For i 0 To 9a Int(Rnd() * 90) …

51单片机STC8H8K64U通过RA8889/RA8876如何控制彩屏(源码下载)

【硬件部份】 一、硬件连接实物&#xff1a; STC8H系列单片机不需要外部晶振和外部复位&#xff0c;在相同的工作频率下&#xff0c;速度比传统的8051单片机要快12倍&#xff0c;具有高可靠抗干扰的优秀特性&#xff0c;与瑞佑的RA8889/RA8876控制芯片刚好可以完美搭配用于工…

Ubuntu24.04下安装docker,并pull ubuntu22.04,然后编译安装vpp

一、docker安装说明 解决官方源无法下载的问题 二、使用步骤 1.更新软件包索引 sudo apt update2.安装必要的软件包&#xff0c;以允许apt通过HTTPS使用仓库 sudo apt install apt-transport-https ca-certificates curl software-properties-common3.添加Docker的官方GPG…

【Chapter7】虚拟存储系统,计算机操作系统教程,第四版,左万利,王英

文章目录 [toc]零、前言一、外存资源管理1.1 外存空间划分1.2 外存空间分配1.2.1 空闲块链(慢)1.2.2 空闲块表(UNIX)1.2.3 字位映像图 1.3 进程与外存对应关系 二、虚拟页式存储系统2.1 基本原理2.2 内存页框分配策略2.3 外存块的分配策略2.4 页面调入时机2.5 置换算法2.5.1 最…

探索AI世界系列:俗说AI智能体

AI agent&#xff0c;翻译为中文就是AI智能体。 什么是AI智能体呢&#xff1f; 一&#xff0c;GPT对AI智能体的定义 AI智能体&#xff0c;即人工智能体&#xff08;Artificial Intelligence Agent&#xff09;&#xff0c;是具有自主性、学习能力和推理能力的计算机程序。 …

手把手教你使用kimi创建流程图【实践篇】

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 引言 在昨日的文章中&#xff0c;我们介绍了如何使用Kimi生成论文中的流程图。今天&#xff0c;我们将更进一步&#xff0c;通过实践案例来展示Kimi在生成流程图方面的应用。这不仅将加…

基于 JuiceFS 构建高校 AI 存储方案:高并发、系统稳定、运维简单

中山大学的 iSEE 实验室&#xff08;Intelligence Science and System) Lab&#xff09;在进行深度学习任务时&#xff0c;需要处理大量小文件读取。在高并发读写场景下&#xff0c;原先使用的 NFS 性能较低&#xff0c;常在高峰期导致数据节点卡死。此外&#xff0c;NFS 系统的…

[SAP ABAP] 汇总内表数据

在加入新数据记录时&#xff0c;将非数值字段具有相同内容记录的数值字段汇总 语法格式 COLLECT <wa> INTO <itab>. <wa>&#xff1a;代表工作区 <itab>&#xff1a;代表内表 示例1 结果显示&#xff1a;

django restframework 多对多模型 —— python

模型 图书和作者是多对多关系 class Book(models.Model):book_namemodels.CharField(max_length40)pricemodels.DecimalField(max_digits4,decimal_places2)publishmodels.ForeignKey(to"Publish",on_deletemodels.CASCADE,related_name"publish")authorm…

ModuleNotFoundError: No module named ‘gdal‘

第一步检查gdal包是否正确安装&#xff1a; conda list 已经安装显示如下 若查找不到&#xff1a;请按照此说明步骤进行安装&#xff1a;ModuleNotFoundError: No module named ‘osgeo‘_modulenotfounderror: no module named osgeo-CSDN博客 第二步&#xff1a;检查是否可以…

VSCode运行前端项目-页面404

背景&#xff1a; 通过VSCode运行前端本地项目&#xff0c;运行成功后打开本地链接&#xff1a;http://1x.xxx.x.xxx:9803/ &#xff0c;发现打开的页面重定向到404&#xff1a;http//1xx.xxx.x.xxx:9803/404&#xff1b; 并且控制台出现&#xff1a;Failed to load resource: …