Django(视图 CBV、FBV)

时间:2021-01-16 16:45:41

day67

参考:http://www.cnblogs.com/liwenzhou/articles/8305104.html

CBV和FBV

我们之前写过的都是基于函数的view,就叫FBV。还可以把view写成基于类的。

就拿我们之前写过的添加班级为例:

FBV版:

Django(视图 CBV、FBV)
# FBV版添加班级
def add_class(request):
if request.method == "POST":
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
return render(request, "add_class.html")
Django(视图 CBV、FBV)

CBV版:

Django(视图 CBV、FBV)
# CBV版添加班级
from django.views import View class AddClass(View): def get(self, request):
return render(request, "add_class.html") def post(self, request):
class_name = request.POST.get("class_name")
models.Classes.objects.create(name=class_name)
return redirect("/class_list/")
Django(视图 CBV、FBV)

注意:

使用CBV时,urls.py中也做对应的修改:

# urls.py中
url(r'^add_class/$', views.AddClass.as_view()),

request对象

当一个页面被请求时,Django就会创建一个包含本次请求原信息的HttpRequest对象。
Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成地使用 request 参数承接这个对象。

官方文档

请求相关的常用值

  • path_info     返回用户访问url,不包括域名
  • method        请求中使用的HTTP方法的字符串表示,全大写表示。
  • GET              包含所有HTTP  GET参数的类字典对象
  • POST           包含所有HTTP POST参数的类字典对象
  • body            请求体,byte类型 request.POST的数据就是从body里面提取到的

request对象
            1. 之前学过的
                1. request.method    --> 获取请求的方法(GET、POST等)
                2. request.GET       --> 通常用来获取URL里面的参数   
                    127.0.0.1:8000/edit_book/?id=1&name=yimi
                    request.GET --> {"id":1, "name":"yimi"}
                    request.GET.get("id")
                3. request.POST      --> 用来获取POST提交过来的数据
                    request.POST.get("book_name")
            2. 补充其他常用的:
                1. request.path_info   --> 获取用户请求的路径(不包含IP和端口和URL参数)
                2. request.body

 mysiteday62/views.py(片段)

request.path_info
request.body

 from django.views import View
# CBV版 添加新的出版社
class AddPublisher(View):
# get和post分开
def get(self, request):
print(request.path_info)
print(request.body)#get中没有数据
print("=" * 120)
return render(request, "add_publisher.html") def post(self, request):
print(request.body) #为提交的数据
# b'publisher_name=%E4%B8%8B%E6%B2%99%E5%87%BA%E7%89%88%E7%A4%BE'
print("=" * 120)
new_name = request.POST.get("publisher_name", None)
if new_name:
# 通过ORM去数据库里新建一条记录
models.Publisher.objects.create(name=new_name)
# 引导用户访问出版社列表页,查看是否添加成功 --> 跳转
return redirect("/publisher_list/")
else:
error_msg = "出版社名字不能为空!"
return render(request, "add_publisher.html", {"error": error_msg})

使用CBV时,urls.py中也做对应的修改:

Django(视图 CBV、FBV)

request.path_info
request.body

的值

Django(视图 CBV、FBV)

上传文件

mysiteday67/app01/views.py(片段)

# 处理上传文件的函数
def upload(request):
"""
保存上传文件前,数据需要存放在某个位置。默认当上传文件小于2.5M时,django会将上传文件的全部内容读进内存。从内存读取一次,写磁盘一次。
但当上传文件很大时,django会把上传文件写到临时文件中,然后存放到系统临时文件夹中。
:param request:
:return:
"""
if request.method == "POST":
print(request.FILES)
print('filename:', request.FILES["upload_file"].name)
# 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
filename = request.FILES["upload_file"].name
# # 在项目目录下 新建一个文件
with open(filename, "wb") as f:
# 从上传的文件对象中一点一点读
for i in request.FILES["upload_file"].chunks():
# 写入本地文件 写入本地文件
f.write(i)
return HttpResponse("上传OK") else:
return render(request, "upload.html")

upload.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body> <form action="/upload/" method="post" enctype="multipart/form-data">
<input type="file" name="upload_file">
{# <input type="file" name="upload_file2">#}
<input type="submit" value="开始上传">
</form> </body>
</html> {#app01#}

上传文件

Django(视图 CBV、FBV)

文件名:

Django(视图 CBV、FBV)

Response对象

与由Django自动创建的HttpRequest对象相比,HttpResponse对象是我们的职责范围了。我们写的每个视图都需要实例化,填充和返回一个HttpResponse。

HttpResponse类位于django.http模块中。

response
            1. HttpResponse        --> 返回字符串内容
            2. render              --> 返回一个html页面              
            3. redirect            --> 返回一个重定向(告诉浏览器再去访问另外的网址)            
            4. JsonResponse

Django(视图 CBV、FBV)

列表特殊

Django(视图 CBV、FBV)

Django的路由系统:https://www.cnblogs.com/liwenzhou/articles/8271147.html

Django的路由系统

Django 1.11版本 URLConf官方文档

URL配置(URLconf)就像Django 所支撑网站的目录。它的本质是URL与要为该URL调用的视图函数之间的映射表。

你就是以这种方式告诉Django,对于这个URL调用这段代码,对于那个URL调用那段代码。

URLconf配置

基本格式:

from django.conf.urls import url

urlpatterns = [
url(正则表达式, views视图函数,参数,别名),
]

参数说明:

  • 正则表达式:一个正则表达式字符串
  • views视图函数:一个可调用对象,通常为一个视图函数或一个指定视图函数路径的字符串
  • 参数:可选的要传递给视图函数的默认参数(字典形式)
  • 别名:一个可选的name参数

正则表达式详解

基本配置

Django(视图 CBV、FBV)
from django.conf.urls import url

from . import views

urlpatterns = [
url(r'^articles/2003/$', views.special_case_2003),
url(r'^articles/([0-9]{4})/$', views.year_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/$', views.month_archive),
url(r'^articles/([0-9]{4})/([0-9]{2})/([0-9]+)/$', views.article_detail),
]
Django(视图 CBV、FBV)

注意事项

  1. urlpatterns中的元素按照书写顺序从上往下逐一匹配正则表达式,一旦匹配成功则不再继续。
  2. 若要从URL中捕获一个值,只需要在它周围放置一对圆括号(分组匹配)
  3. 不需要添加一个前导的反斜杠,因为每个URL 都有。例如,应该是^articles 而不是 ^/articles。
  4. 每个正则表达式前面的'r' 是可选的但是建议加上。

分组匹配

实践:

Django(视图 CBV、FBV)

匹配传参数:

mysiteday67

Django(视图 CBV、FBV)

上图圆括号中内容,对应下图del_id。{{publisher.id}} -> ([0-9]+)  ->  del_id

Django(视图 CBV、FBV)

分组命名匹配

上面的示例使用简单的正则表达式分组匹配(通过圆括号)来捕获URL中的值并以位置参数形式传递给视图。

在更高级的用法中,可以使用分组命名匹配的正则表达式组来捕获URL中的值并以关键字参数形式传递给视图。

在Python的正则表达式中,分组命名正则表达式组的语法是(?P<name>pattern),其中name是组的名称,pattern是要匹配的模式。

Django(视图 CBV、FBV)

2. 分组匹配        --> 相当于给视图函数传递位置参数
 3. 分组命名匹配    --> 相当于给视图函数传递关键字参数
            (两个不要混合使用)

include其他的URLconfs

Django(视图 CBV、FBV)

传递额外的参数给视图函数(了解)

URLconfs 具有一个钩子,让你传递一个Python 字典作为额外的参数传递给视图函数。

django.conf.urls.url() 函数可以接收一个可选的第三个参数,它是一个字典,表示想要传递给视图函数的额外关键字参数。

举例:

Django(视图 CBV、FBV)