您的位置:首页 > 编程语言 > Go语言

django视图

2021-06-26 19:31 1916 查看

django视图

视图就是一个普通的Python函数,它接收从urls哪里的HttpRequest对象,返回的是HTML网页、重定向、404错误,XML文档或图像等任何东西。

一般使用

from django.http import HttpResponse
# Create your views here.

def index(request):
return HttpResponse("<h1>hello world</h1>")

例子,返回的是一个h1标签。

接收参数

当我们在路由设置参数时,在视图中应该要有对应的形参接收。

# app/urls.py

from django.urls import path
from .views import index, article

app_name = "app01"

urlpatterns = [
# url中有个参数叫article_id,视图函数是article
path("article/<int:article_id>", article, name="article")
]
# app/views.py

from django.http import HttpResponse
# Create your views here.

def article(request, article_id):
return HttpResponse(f"article的id是{article_id}")

返回

视图函数返回各种数据,一般只需用到

django.shortcuts
下面的函数即可,该模块,为我们提供了很多快捷方便的类和方法,它们都很重要,使用频率很高。

HTML页面

使用

django.shortcuts.render
函数。

from django.shortcuts import render

def index(request):
return render(request, "app01/index.html")

render(request, template_name, context=None, content_type=None, status=None, using=None)

必需参数:

  • request:视图函数处理的当前请求,封装了请求头的所有数据,其实就是视图参数request。
  • template_name:要使用的模板的完整名称或者模板名称的列表。如果是一个列表,将使用其中能够查找到的第一个模板。

可选参数:

  • context:添加到模板上下文的一个数据字典。默认是一个空字典。可以将认可需要提供给模板的数据以字典的格式添加进去。这里有个小技巧,使用Python内置的locals()方法,可以方便地将函数作用域内的所有变量一次性添加进去。
  • content_type:用于生成的文档的MIME类型。 默认为DEFAULT_CONTENT_TYPE设置的值,也就是'text/html'。
  • status:响应的状态代码。 默认为200。
  • using:用于加载模板使用的模板引擎的NAME。

template_name一般是在app/templates/app/下的html文件。多写一个"app"目的是区分不同的app中的同名html,因为假如settins的TEMPLATES中的APP_DIRS为True时,django会在app/templates下寻找html文件,所以要加上一层app名字。

使用render本质就是:

from django.http import HttpResponse
from django.template import loader

def my_view(request):

t = loader.get_template('myapp/index.html')
c = {'foo': 'bar'}
return HttpResponse(t.render(c, request), content_type='application/xhtml+xml')

使用

locals()
作为render的context参数,可以将视图中的全部局部变量给template。

Json数据

django返回json数据的方法有很多,下面介绍几种方法:

  1. 使用

    django.http.HttpRespone
    库+
    json

    直接使用json库序列化数据,然后使用HttpRespone返回数据,指定请求头Content-Type=application/json。
    序列化非 常用数据类型时,可以指定编码器(一个继承json.JSONEncoder的类,重写default方法)。

    from django.http import HttpResponse
    
    import json
    
    def index(request):
    data = {
    "name": "lczmx",
    "age": 22,
    }
    
    return HttpResponse(json.dumps(data), content_type="application/json")
  2. 使用

    django.http.HttpRespone
    库+
    django.core.serializers

    此方法可以很好的序列化QuerySet对象。

    def index(request):
    questions = Question.objects.all()
    data = serializers.serialize("json", queryset=questions)
    return HttpResponse(data, content_type="application/json")

    serializers.serialize
    的第一个参数是格式,第二个参数是queryset数据。
    更多见官方文档:序列化 Django 对象

  3. 使用

    django.http.JsonResponse

    class JsonResponse(data, encoder=DjangoJSONEncoder, safe=True, json_dumps_params=None, **kwargs)

    JsonResponse是一个 HttpResponse 子类,帮助创建一个 JSON 编码的响应。它继承了它的超类的大部分行为,但有一些不同:
    其默认的 Content-Type 头设置为 application/json。

      第一个参数 data 应该是 dict 实例。如果 safe 参数设置为 False (见下文),它可以是任何 JSON 可序列化的对象。
    • encoder,默认为 django.core.serializers.json.DjangoJSONEncoder,将用于序列化数据。。
    • safe 布尔参数默认为 True。如果它被设置为 False,任何对象都可以被传递到序列化中(否则只允许 dict 实例)。如果 safe 为 True,而第一个参数是一个非 dict 对象,则会引发一个 TypeError。
    • json_dumps_params 参数是一个关键字参数的字典,用来传递给 json.dumps() 调用,用于生成响应。
    from django.http import JsonResponse
    
    def index(request):
    data = {
    "name": "lczmx",
    "age": 22,
    }
    
    return JsonResponse(data)

跳转页面

跳转页面使用redirect进行页面跳转。

redirect(to, args, permanent=False, *kwargs)

根据传递进来的url参数,返回HttpResponseRedirect。

参数to可以是:

  • 一个模型实例:将调用模型的get_absolute_url()函数,反向解析出目的url;
  • URL的name名称:可能带有参数:reverse()将用于反向解析url;
  • 一个绝对的或相对的URL:将原封不动的作为重定向的目标位置。
    默认情况下是临时重定向,如果设置permanent=True将永久重定向。

例子:

# urls.py
from django.urls import path
from .views import index, article

app_name = "app01"

urlpatterns = [
path("index/", index, name="index"),
path("article/<int:article_id>", article, name="article")
]

# views.py

from django.http import HttpResponse
from django.shortcuts import redirect
# Create your views here.

def index(request):
return HttpResponse("index page")

def article(request, article_id):
if article_id > 123:
return redirect("app01:index")
return HttpResponse(f"article的id是{article_id}")

错误信息

django实现了一些状态码以4和5开头的HttpRespone子类,点击查看。
假如没有我们需要的,可以自定义响应类,只需要继承HttpRespone类,然后指定

status_code
属性的值即可。

from http import HTTPStatus
from django.http import HttpResponse

class HttpResponseNoContent(HttpResponse):
status_code = HTTPStatus.NO_CONTENT

404
为了方便,django提供了

django.http.Http404
异常类,在视图中主动抛出这个异常时,Django 会捕捉到它并且返回标准的错误页面,连同 HTTP 错误代码 404 。

from django.http import Http404

def article(request, article_id):
if article_id > 123:
raise Http404("page not fund")
return HttpResponse(f"article的id是{article_id}")

虽然可以返回404页面,但是这是django内置的404页面,在实际使用中,需要换成我们自己的。
需要注意的是,要使用自定义的404html,需要将settings文件中的DEBUG设为False。

由于当你raise了Http404后:
django会做一下动作:

  1. django.conf.urls.handler404,这相当于一个urls文件:
# __init__文件的内容
from django.urls import include, re_path
from django.views import defaults

__all__ = ['handler400', 'handler403', 'handler404', 'handler500', 'include', 'url']

handler400 = defaults.bad_request
handler403 = defaults.permission_denied
handler404 = defaults.page_not_found
handler500 = defaults.server_error
# ...
  1. 使用
    django.views.defaults.page_not_found()
    视图
  2. 判断是否自定义了404.html,
      如果有(查找的是template,和一般的一样),输出该HTML文件
    • 如果没有,输出默认的404提示信息

所以我们要自定以404页面有两个方法:

  1. 使用默认的
    django.views.defaults.page_not_found()
    视图,然后再自己在template中创建404.html文件。
  2. 自定义处理404的视图

第一种方法:

  1. 在template创建一个404页面
    注意要配置好settings.TEMPLATES的DIRS或APP_DIRS。

  2. 使用静态的页面或使用django的模板引擎展示更多详细信息。
    简化django的page_not_found视图,发现其主要做了以下内容:

    template.render(context = {
    'request_path': quote(request.path),
    'exception': exception.args[0]}, request)
    
    # quote为urllib.parse.quote
    # 作用是对url进行url编码

    因此我们可以在404.html中利用模板引擎拿到context。其中:request_path是你当前的url,exception是异常类的信息,比如这样定义404.html:

    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>PageNotFound</title>
    </head>
    <body>
    <h1>404页面</h1>
    <p>不存在的链接:{{ request_path }}</p>
    <p>提示:{{ exception }}</p>
    </body>
    </html>

第二种方法:
步骤:

  1. 根urls中,定义handler404,使其的值为自己处理404的视图
  2. 完成404视图的编写
    比如:
# 根urls.py
from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path("app01/", include("app01.urls")),
]
handler404 = "app01.views.page_not_found"
# 看有些博客用的是
# handler404 = views.page_not_found # handler404直接等于一个视图函数
# 但官方的例子是使用字符串的
# views.py
@requires_csrf_token
def page_not_found(request, exception):
# ....
# ....
return render(request, 'errors/404.html')

注意:一定要在根定义handler404,否则会老是用默认的!!!(我用的是django3.0.1,其他版本django不知道)

关于其他诸如400、403等页面,其自定义方法也是这样,不过是把

handler的视图
状态码.html
换成对应的
。对于前种方法,官方给了一些的例子:自定义报错视图

HttpRequest对象

关于HttRequest的各种属性见官方文档:HttpRequest

一些常用的(表中的request指定的HttpRequest对象):

属性 说明
request.scheme 协议http or https
request.path 返回完整路径,形如:"/app/index"
request.path_info 路径的路径信息部分
request.method HTTP 方法,大写
request.GET get参数,属于QueryDict对象
request.POST post参数, 属于QueryDict对象
request.COOKIES 一个包含所有 cookies 的字典。键和值是字符串。
request.FILES 一个类似字典的对象,包含所有上传的文件
request.headers 请求中的所有HTTP头,是一个不区分大小写的类似字典的对象

取参数

这里的取参数指的是取get或者post的参数,由于request.GET和request.POST对属于QueryDict对象,所以先了解一下

django.http.request.QueryDict
对象:

  1. QueryDict是对http请求数据的封装
  2. QueryDIct是dict的子类,所以很多使用方法和字典一样
  3. 一般只需要使用get方法即可(和字典的一样用),其他方法点击这里查看。

所以取get和post参数:

def t(request):
if request.method == "GET":
print(request.GET.get("name"))
print(request.GET.get("age"))
elif request.method == "POST":
print(request.POST.get("name"))
print(request.POST.get("age"))
return HttpResponse("ok!")

注意使用POST方式提交时,要在form表单中加上{% csrf_token %}标签,至于使用ajax提交post请求,见后文大标题

HttpRespone对象

HttpResponse对象则是你想要返回给浏览器的数据的封装。
我们编写的每个视图都要实例化、填充和返回一个HttpResponse对象。也就是函数的return值。
HttpRespone可以传递一个一个string、bytes或者memoryview或可迭代对象。

常用属性

属性 说明
content 响应的内容。bytes类型。
charset 编码的字符集。 如果没指定,将会从content_type中解析出来。
status_code 响应的状态码,比如200。

常用方法

方法 说明
has_header(header) 检查头部中是否有给定的名称(不区分大小写),返回True或 False。
setdefault(header, value) 当该头字段不存在时,设置一个头部
delete_cookie() 删除一个Cookie,参数见下文

更多点击这里查看

设置与删除响应头字段

from django.http import HttpResponse

def index(request):
response = HttpResponse()
# 通过中括号设置值
response["name"] = "lczmx"
response["age"] = 20
response.setdefault("age", 22)
# 使用del删除头字段
# key不存在时,不会报错
del response["name"]
return response

cookie与session

HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。为了给客户端们一个通行证,W3C组织提出了Cookie。
Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务 器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
由于Cookie存在不安全、大小有限制、受制于同源策略等缺点,所以除了使用Cookie,Web应用程序中还经常使用Session来记录客户端状态。Session是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。

下面的内容需要注意方法的对象是respone还是request

Cookie

设置Cookie
使用HttpResponse对象的set_cookie方法设置一个 cookie。参数与 Python 标准库中的 Morsel cookie 对象相同:

HttpResponse.set_cookie(key, value='', max_age=None, expires=None, path='/', domain=None, secure=False, httponly=False, samesite=None)
  • key是cookie的键
  • value是cookie的值
  • max_age是cookie的生存周期
    以秒为单位。如果设为None,浏览器开启期间保持,关闭后一同删除。
  • expires是到期时间
    格式为 "Wdy, DD-Mon-YY HH:MM:SS GMT" 的字符串,或者是 UTC 的 datetime.datetime 对象。
    如果 expires 是一个 datetime 对象,将计算 max_age。
    如:datetime.datetime.utcnow() + datetime.timedelta(days=7)
  • domain用于设置跨域的Cookie
    例如domain=".lawrence.com"将设置一个www.lawrence.com、blogs.lawrence.com和calendars.lawrence.com都可读的Cookie。 否则,Cookie将只能被设置它的域读取。
  • secure是否支持https,为True时支持https
  • httponl,为True时阻止客户端的js代码访问cookie

注意cookie不要超过 4096 字节

获取Cookie
使用HttpRequest.COOKIES对象的get方法:
如:

request.Cookie.get("key")

删除Cookie
HttpResponse.delete_cookie(key, path='/', domain=None, samesite=None)
删除给定键的 cookie。如果键不存在,则静默失败。

  • key是键
  • path和domain应该与set_cookie()中使用的值相同,否则Cookie不会删掉

例子

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

def auth_login(req_func):
"""
用于检验登录信息的装饰器
:param req_func:
:return:
"""
def wap(*args, **kwargs):
req = args[0]
# 获取cookie
if req.COOKIES.get("username") != "lczmx":
url = reverse("app01:login") + "?next=%s" % req.path
return redirect(url)
return req_func(*args, **kwargs)
return wap

@auth_login
def index(request):
return render(request, "app01/index.html")

def login(request):
next_url = request.GET.get("next")

if request.method == "GET":
return render(request, "app01/login.html", {"next_url": next_url})
elif request.method == "POST":
username = request.POST.get("username")
pwd = request.POST.get("password")
if username == "lczmx" and pwd == "123456":     # 假装验证了
ret = redirect(next_url)
# 设置cookie
ret.set_cookie("username", "lczmx")
else:
ret = HttpResponse("验证失败")
return ret

def logout(request):
ret = HttpResponse("success")
# 删除cookie
ret.delete_cookie("username")
return ret

Session

由于django的session依赖中间件:SessionMiddleware,所以要用session的时候不要去掉 MIDDLEWARE中的

django.contrib.sessions.middleware.SessionMiddleware

session操作都要使用到HttpRequest.session对象,这是一个可读可写的,类似字典的对象,代表当前会话。

设置Session

request.session["name"] = "lczmx"

获取Session

request.session.get("lczmx")

删除Session

del request.session["lczmx"]

[更多关于session的方法【包括session的保存方式】(https://docs.djangoproject.com/zh-hans/3.2/topics/http/sessions/#using-sessions-in-views)

设置session的保存时间

request.set_expiry(value)

为会话设置过期时间。你可以传递很多不同值:

  • 如果 value 是整型,会话将在闲置数秒后过期。比如,调用 request.session.set_expiry(300) 会使得会话在5分钟后过期。
  • 如果 value 是一个 datetime 或 timedelta 对象,会话将在指定的 date/time 过期。注意,如果你正在使用 PickleSerializer ,那么 datetime 和 timedelta 的值只能序列化。
  • 如果 value 是 0 ,则当浏览器关闭后,用户会话 cookie 将过期。
  • 如果 value 是 None ,会话会恢复为全局会话过期策略。
    出于过期目的,读取会话不被视为活动。会话过期时间会在会话最后一次修改后开始计算。

django装饰器

内置的装饰器

部分内容转载于这里:常用装饰器应用场景及正确使用方法

django.views.decorators.http

from django.views.decorators.http import require_http_methods

@require_http_methods(["GET", "POST"])
def my_view(request):
# I can assume now that only GET or POST requests make it this far
# ...
pass

一些类似的装饰器:
require_GET:装饰器可以要求视图只接受 GET 方法。
require_POST:装饰器可以要求视图只接受 POST 方法。
require_safe:装饰器可以要求视图只接收 GET 和 HEAD 方法。这些方法通常被认为是安全的,因为它们除了检索请求的资源外,没有特别的操作。

django.contrib.auth.decorators

权限验证

  1. @login_required

    @login_required是Django最常用的一个装饰器。其作用是在执行视图函数前先检查用户是否通过登录身份验证,并将未登录的用户重定向到指定的登录url。其中login_url是可选参数。如果不设置,默认login_url是settings.py里设置的LOGIN_URL。

    from django.contrib.auth.decorators import login_required
    
    @login_required(login_url='/accounts/login/')
    def my_view(request):
    ...

    @login_required还可以一个可选参数是redirect_field_name, 默认值是'next'。

    from django.contrib.auth.decorators import login_required
    
    @login_required(redirect_field_name='my_redirect_field')
    
    def my_view(request):
    
    ...

    注意:

    login_required装饰器不会检查用户是否是is_active状态。如果你想进一步限制登录验证成功的用户对某些视图函数的访问,你需要使用更强大的

    @user_passes_test
    装饰器。

  2. @user_passes_test

    @user_passes_test
    装饰器的作用是对登录用户对象的信息进行判断,只有通过测试(返回值为True)的用户才能访问视图函数。不符合条件的用户会被跳转到指定的登录url。

    @user_passes_test
    装饰器有一个必选参数,即对用户对象信息进行判断的函数。该函数必需接收user对象为参数、返回一个布尔值。其与login_required类似,@user_passes_test还有两个可选参数(login_url和redirect_field_name),这里就不多讲了。

    user_passes_test(func[,login_url=None, redirect_field_name=REDIRECT_FIELD_NAME])

    下例中

    @user_passes_test
    装饰器对用户的email地址结尾进行判断,会把未通过测试的用户会定向到登录url。试想一个匿名用户来访问,她没有email地址,显然不能通过测试,登录后再来吧。

    from django.contrib.auth.decorators import user_passes_test
    
    def email_check(user):
    return user.email.endswith('@example.com')
    
    @user_passes_test(email_check)
    def my_view(request):
    ...

    如果需要加可选参数,可以按如下方式使用。

    @user_passes_test(email_check, login_url='/login/'):
    def my_view(request):
    ...

    注意:

    @user_passes_test
    不会自动的检查用户是否是匿名用户,但是
    @user_passes_test
    装饰器还是可以起到两层校验的作用。一来检查用户是否登录,二来检查用户是否符合某些条件,无需重复使用
    @login_required
    装饰器。

    我们如果只允许

    is_active
    的登录用户访问某些视图,我们现在可以使用@user_passes_test装饰器轻松地解决这个问题,如下所示:

    from django.contrib.auth.decorators import user_passes_test
    
    @user_passes_test(lambda u: u.is_active)
    def my_view(request):
    ...
  3. @permission_required

    @permission_required
    装饰器的作用是检查用户用户是否有特定权限,第一个参数perm是权限名,为必选, 第二个参数login_url为可选。

    permission_required(perm[, login_url=None, raise_exception=False])

    下例检查用户是否有polls.can_vote的权限,没有的话定向至login_url。如果你设置了raise_exception=True, 会直接返回403无权限的错误,而不会跳转到登录页面。那么问题来了,我们需要先使用@login_required来验证用户是否登录,再使用

    @permission_required
    装饰器来查看登录用户是否具有相关权限吗? 答案是不需要。如果一个匿名用户来访问这个视图,显然该用户没有相关权限,会自动定向至登录页面

    from django.contrib.auth.decorators import permission_required
    
    @permission_required('polls.can_vote', login_url='/login/')
    def my_view(request):
    ...

django.views.decorators.cache

这个模块下的装饰器适用于缓存的,缓存是Django装饰器很重要的一个应用场景。下面我们来看几个主要的缓存装饰器。注意: 使用以下装饰器的前提是你已经对缓存进行了相关设置。

  1. @cache_page

    该装饰器可以接收缓存的时间作为参数,比如下例缓存页面15分钟。

    from django.views.decorators.cache import cache_page
    
    @cache_page(60 * 15)
    def my_view(request):
    ...
  2. @cache_control

    通常用户将会面对两种缓存: 他或她自己的浏览器缓存(私有缓存)以及他或她的提供者缓存(公共缓存)。 公共缓存由多个用户使用,而受其它人的控制。 这就产生了你不想遇到的敏感数据的问题,比如说你的银行账号被存储在公众缓存中。 因此,Web 应用程序需要以某种方式告诉缓存那些数据是私有的,哪些是公共的。

    cache_control
    装饰器可以解决这个问题。

    from django.views.decorators.cache import cache_control
    
    @cache_control(private=True)
    def my_view(request):
    ...

    该修饰器负责在后台发送相应的 HTTP 头部。还有一些其他方法可以控制缓存参数。 例如, HTTP 允许应用程序执行如下操作:

      定义页面可以被缓存的最大时间。

    • 指定某个缓存是否总是检查较新版本,仅当无更新时才传递所缓存内容。

    在 Django 中,可使用

    cache_control
    视图修饰器指定这些缓存参数。 在下例中,
    cache_control
    告诉缓存对每次访问都重新验证缓存并在最长 3600 秒内保存所缓存版本。

    from django.views.decorators.cache import cache_control
    
    @cache_control(must_revalidate=True, max_age=3600)
    def my_view(request):
    ...

    cache_control
    中,任何合法的Cache-Control HTTP 指令都是有效的。下面是完整列表:

    public=True
    private=True
    no_cache=True
    no_transform=True
    must_revalidate=True
    proxy_revalidate=True
    max_age=num_seconds
    s_maxage=num_seconds
  3. @vary_on_headers

    缺省情况下,Django 的缓存系统使用所请求的路径(如blog/article/1)来创建其缓存键。这意味着不同用户请求同样路径都会得到同样的缓存版本,不考虑客户端user-agent, cookie和语言配置的不同, 除非你使用Vary头部通知缓存机制需要考虑请求头里的cookie和语言的不同。
    要在 Django 完成这项工作,可使用便利的

    vary_on_headers
    视图装饰器。例如下面代码告诉Django读取缓存数据时需要同时考虑User-Agent和Cookie的不同。与此类似的装饰器还有
    @vary_on_cookie

    from django.views.decorators.vary import vary_on_headers
    
    @vary_on_headers('User-Agent', 'Cookie')
    def my_view(request):
    ...
  4. @never_cache

    如果你想用头部完全禁掉缓存, 你可以使用

    @never_cache
    装饰器。如果你不在视图中使用缓存,服务器端是肯定不会缓存的,然而用户的客户端如浏览器还是会缓存一些数据,这时你可以使用
    never_cache
    禁用掉客户端的缓存。

    from django.views.decorators.cache import never_cache
    
    @never_cache
    def myview(request):
    # ...

其它常用装饰器

@method_decorator

前面的案例中,我们的装饰器都是直接使用在函数视图上的。如果需要在基于类的视图上使用装饰器,我们需要使用到

@method_decorator
这个装饰器, 它的作用是将类伪装成函数方法。
@method_decorator
第一个参数一般是需要使用的装饰器名。

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.views.generic import TemplateView

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'

常用自定义装饰器

关于一些自定义装饰器,见:详解Django中六个常用的自定义装饰器

使用多重装饰器

你可以在一个函数或基于类的视图上使用多重装饰器,但一定要考虑装饰器执行的先后顺序。比如下例中会先执行

@never_cache
, 再执行
@login_required

from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator

from django.views.decorators.cache import never_cache

@method_decorator(never_cache, name='dispatch')

@method_decorator(login_required, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'

class ProtectedView(TemplateView):
template_name = 'secret.html'

上例等同于:

decorators = [never_cache, login_required]

@method_decorator(decorators, name='dispatch')
class ProtectedView(TemplateView):
template_name = 'secret.html'

上传文件

https://docs.djangoproject.com/zh-hans/3.2/topics/http/file-uploads/

FBV及CBV

FBV是指以函数的形式定义视图,而CBV是指以类的形式定义视图。
二者各有优点,FBV胜在灵活、简便,而CBV在某些场景中可以极大地降低代码复用。
要使用类视图,主要有一下几个要点:

  1. views.py中自定义一个继承
    django.views.View
    的类
  2. 为自定义类添加请求方法的方法,即get请求就添加get方法
  3. 在urls.py中,指定path的第二个参数为类名.as_view()
# views.py
from django.views import View

class CView(View):
def get(self, request):
return render(request, "app01/index.html")

# urls.py
from .views import CView
app_name = "app01"

urlpatterns = [
path("cview/", CView.as_view(), name="cview"),
]

除了

django.views.View
外,django还有一些内置的类视图,点击查看:内置基于类的视图 API

我的github
我的博客
我的笔记

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: