Django(视图)

day67

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

CBV和FBV

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

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

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")
复制代码

CBV版:

复制代码
# 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/")
复制代码

注意:

使用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

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

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

request.path_info
request.body

的值

上传文件

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#}

 上传文件

 文件名:

Response对象

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

HttpResponse类位于django.http模块中。

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

 

 列表特殊

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参数

 

正则表达式详解

基本配置

复制代码
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), ]
复制代码

注意事项

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

分组匹配

实践:

匹配传参数:

mysiteday67

分组命名匹配

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

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

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

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

include其他的URLconfs

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

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

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

举例:

猜你喜欢

转载自www.cnblogs.com/112358nizhipeng/p/10353172.html