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

Django 之 视图层

2019-06-11 20:21 363 查看

视图层

一个视图就是Python的一个函数。这个函数第一个参数的类型是HttpRequest;它返回一个HttpResponse实例。为了使一个Python的函数成为一个Django可识别的视图,它必须满足这两个条件。

视图函数的代码写哪里都可以,但一般约定俗成设置在项目或应用程序目录中的 views.py 文件中。下面是一个以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对象。

HttpRequest对象

django将请求报文中的请求行、首部信息、内容主体封装成 HttpRequest 类中的属性。 除了特殊说明的之外,其他均为只读的

request对象的属性

request.scheme:代表请求的方案,http或者https

request.path:请求的路径,比如请求127.0.0.1/org/list,那这个值就是/org/list

request.method:表示请求使用的http方法,GET或者POST请求

request.encoding:表示提交数据的编码方式

request.GET:获取GET请求

request.POST:获取post的请求,比如前端提交的用户密码,可以通过request.POST.get()来获取

request.COOKIES:包含所有的cookie

request.session:一个既可读又可写的类似于字典的对象,表示当前的会话。只有当Django 启用会话的支持时才可用。

request.FILES:一个类似于字典的对象,包含所有的上传文件信息。 FILES 中的每个键为<input type=“file” name="" /> 中的name,值则为对应的数据。

注意,FILES 只有在请求的方法为POST 且提交的<form> 带有enctype=“multipart/form-data” 的情况下才会 包含数据。否则,FILES 将为一个空的类似于字典的对象。另外:如果使用 POST 上传文件的话,文件信息将包含在 FILES 属性中

包含所有的cookie

request.user:一个

AUTH_USER_MODEL
类型的对象,表示当前登录的用户。

如果用户当前没有登录,

user
将设置为
django.contrib.auth.models.AnonymousUser
的一个实例。你可以通过 is_authenticated() 区分它们。把request传给前端的时候,前端可以通过 {% if request.user.is_authenticated %}判断用户时候登录

request.META:一个标准的Python 字典,包含所有的HTTP 首部。具体的头部信息取决于客户端和服务器,下面是一些示例:

一个标准的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
    —— 服务器的端口(是一个字符串)

上传文件示例

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

HttpResponse对象

响应对象主要有三种形式:

  • HttpResponse()
  • render()
  • redirect()

HttpResponse()

括号内直接跟一个具体的字符串作为响应体。

render()

render(request, template_name[, context])
参数:
request: 用于生成响应的请求对象。
template_name:要使用的模板的完整名称,可选的参数
context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

render方法就是将一个模板页面中的模板语法进行渲染,最终渲染成一个html页面作为响应体。

redirect()

传递要重定向的一个硬编码的URL

def my_view(request):
...
return redirect('/index/')

也可以是一个完整的URL:

def my_view(request):
...
return redirect('http://www.baidu.com/') 

JsonResponse对象

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

from django.http import JsonResponse
response = JsonResponse({'foo': 'bar'})
print(response.content)
b'{"foo": "bar"}'

默认能传递字典类型,如果要传递非字典类型需要设置一下safe关键字参数。

response = JsonResponse([1, 2, 3], safe=False)

CBV和FBV

CBV基于类的视图(Class base view)和FBV基于函数的视图(Function base 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()),
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: