Django – 视图

  • A+
所属分类:Python教程 前端学习

一、Django试图说明

一个视图函数(类),简称视图,是一个简单的Python 函数(类),它接受Web请求并且返回Web响应。

响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片。

无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你当前项目目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,大家约定成俗将视图放置在项目(project)或应用程序(app)目录中的名为views.py的文件中。

1.1、一个简单的试图

下面是一个以HTML文档的形式返回当前日期和时间的视图:

from django.http import HttpResponse
import datetime

def current_datetime(request):
    now = datetime.datetime.now()
    html = "<html><body>It is now %s.</body></html>" % now
    return HttpResponse(html)

让我们来逐行解释下上面的代码:

  • 首先,我们从 django.http模块导入了HttpResponse类,以及Python的datetime库。

  • 接着,我们定义了current_datetime函数。它就是视图函数。每个视图函数都使用HttpRequest对象作为第一个参数,并且通常称之为request。

注意,视图函数的名称并不重要;不需要用一个统一的命名方式来命名,以便让Django识别它。我们将其命名为current_datetime,是因为这个名称能够比较准确地反映出它实现的功能。

  • 这个视图会返回一个HttpResponse对象,其中包含生成的响应。每个视图函数都负责返回一个HttpResponse对象。

Django使用请求和响应对象来通过系统传递状态。

当浏览器向服务端请求一个页面时,Django创建一个HttpRequest对象,该对象包含关于请求的元数据。然后,Django加载相应的视图,将这个HttpRequest对象作为第一个参数传递给视图函数。

每个视图负责返回一个HttpResponse对象。

1.2、CVB于FVB

CBV:基于类的URL对应方法,简称CBV(class base view)
FBV:基于函数的URL对应方法,简称FBV(function base view)
CVB与FVB的urls.py里的对应关系写法的区别
1.FVB的URL与函数对应关系的写法

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^add_press/', views.add_press),       #FBV的添加出版社URL与函数对应关系写法
]

2.CVB的URL与函数对应关系的写法

from django.conf.urls import url
from django.contrib import admin
from app01 import views
urlpatterns = [
    url(r'^add_press/', views.AddPress.as_view()),      #CBV的添加出版社URL与函数对应关系写法
]

FVB与CVB在views.py中的写法示例:
1.基于FVB版的添加出版社代码

def add_press(request):
    err_msg=""         #定义空消息
    if request.method == "POST":        #如果请求是POST请求
        new_name = request.POST.get("press_name", None)        #获取POST请求里德press_name变量赋值给new_name
        if new_name:        #判断如果new_name的值不为空
            models.PressName.objects.create(name=new_name)        #就在pressname表里创建name字段值为new_name
            return redirect("/press/")       #然后返回/press/页面
        else:      #如果new_name的值为空
            err_msg = "内容不能为空!"         #就返回提示消息
    return render(request, "add_press.html",{"error":err_msg})         #如果不是POST请求,返回add_press.html页面,

2.基于CVB版的添加出版社代码

from django.views import View        #导入模块
class AddPress(View):
    def get(self,request):       #get请求的处理方法
        return render(request, "add_press.html")  # 如果是get请求,返回add_press.html页面,

    def post(self,request):       #post请求的处理方法
        err_msg = ""  # 定义空消息
        new_name = request.POST.get("press_name", None)  # 获取POST请求里德press_name变量赋值给new_name
        if new_name:  # 判断如果new_name的值不为空
            models.PressName.objects.create(name=new_name)  # 就在pressname表里添加name字段值为new_name
            return redirect("/press/")  # 然后返回/press/页面
        else:  # 如果new_name的值为空
            err_msg = "内容不能为空!"  # 定义err_msg
            return render(request, "add_press.html", {"error": err_msg})  # 返回add_press.html页面,提示内容为空

二、Request对象与Response对象

2.1、Request对象

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

官方文档

请求相关常用值说明
1.request.path_info:获取用户请求的路径(不包含IP端口和URL参数)

2.request.method:获取请求中使用的HTTP方法(GET、POST等)。

3.request.GET:通常用来获取GET请求URL里面的参数,例如:请求:127.0.0.1:8000/add_book/?id=13。获取:request.GEt.get('id')

4.request.POST:用来获取POST请求提交过来的数据,例如:request.POST.get('name')

5.request.body :请求体,byte类型 request.POST的数据就是从body里面提取到的,不适用于GET请求

上传文件代码示例
1.前端提交表单的html代码如下:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>上传文件</title>
    <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
</head>
<body>

<form action="/upload/" method="post" enctype="multipart/form-data">
    <input type="file" name="upload_file">
    <input type="submit" value="开始上传">
</form>

<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/bootstrap/js/bootstrap.min.js"></script>

</body>
</html>

2.后台处理上传的代码如下:

#处理上传的文件功能
def file_upload(request):
    if request.method == "POST":          #判断是否为post请求
        print(request.FILES)       #结果为:<MultiValueDict: {'upload_file': [<TemporaryUploadedFile: 1.jpg (image/jpeg)>]}>
        print(request.FILES.get("upload_file").name)        #结果为:1.jpg
        # 从请求的FILES中获取上传文件的文件名,file为页面上type=files类型input的name属性值
        filename = request.FILES["upload_file"].name        #也可以这么写:request.FILES.get("upload_file").name
        # 在项目目录下新建一个文件
        with open(filename,"wb") as f:
            # 从上传的文件对象中一点一点读
            for chunk in request.FILES['upload_file'].chunks():
                # 写入本地文件
                f.write(chunk)
        return HttpResponse("上传成功!!")       #返回上传成功
    else:       #不是post请求就执行下面的方法
        return render(request, "file_upload.html")

2.2、Response对象

HttpResponse对象的主要功能用于给浏览器返回字符串。
1.使用

from django.shortcuts import HttpResponse
return HttpResponse("Welcome to 追梦人Blog")

2.属性说明

HttpResponse.content:响应内容
HttpResponse.charset:响应内容的编码
HttpResponse.status_code:响应的状态码

2.3、JsonResponse对象

JsonResponse是HttpResponse的子类,专门用来生成JSON编码的响应。
1.使用

from django.http import JsonResponse      #导入Django专门封装的返回json格式字符串的模块
def json_test(request):
    data = {'name':'张三','age':18}
    return JsonResponse(data)        #自动将data序列化为json格式,然后返回给前端(默认情况下只支持返回字典格式的数据,如果想返回列表格式的数据需要加safe=False参数,例如:return JsonResponse(data,safe=False)  )

2.注意
JsonResponse对象默认只支持将字典格式的数据序列化为json格式返回给浏览器,如果想要将列表格式的数据序列化为json格式就需要加safe=False参数,具体使用如下:

from django.http import JsonResponse      #导入Django专门封装的返回json格式字符串的模块
def json_test(request):
    data = [11,22,33,44]
    return JsonResponse(data,safe=False)        #自动将data序列化为json格式,然后返回给前端(默认情况下只支持返回字典格式的数据,如果想返回列表格式的数据需要加safe=False参数,例如:return JsonResponse(data,safe=False)  )

三、Django shortcut

官方文档

3.1、render()方法

Django - 视图

参数说明:
1.request: 用于生成响应的请求对象。
2.template_name:要使用的模板的完整名称,可选的参数
3.context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。
4.content_type:生成的文档要使用的MIME类型。默认为 DEFAULT_CONTENT_TYPE 设置的值。默认为'text/html'
5.status:响应的状态码。默认为200。
   6.useing: 用于加载模板的模板引擎的名称。
示例

def press(request):
    #获取pressname表里的所有数据并赋值给ret
    ret = models.PressName.objects.all()
    #返回press_list.html页面,将press_list变量名(press_list变量的值为ret)传给press_list.html
    return render(request, "press_list2.html", {"press_list": ret})

3.2、redirect()方法

该参数可以将一个绝对的或相对的URL,将原封不动的作为重定向的位置。
示例
1.重定向到本站的某个路径

def my_view(request):
    ...
    return redirect('/some/url/')     #重定向到指定的路径

2.重定向到指定的网址

def my_view(request):
    ...
    return redirect('https://www.zhuimengren.co/')    #重定向到指定的网址

关于重定向的说明:
临时重定向(响应状态码:302)和永久重定向(响应状态码:301)对普通用户来说是没什么区别的,它主要面向的是搜索引擎的机器人。

A页面临时重定向到B页面,那搜索引擎收录的就是A页面。

A页面永久重定向到B页面,那搜索引擎收录的就是B页面。

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: