Django - - - -视图层之视图函数(views)

视图层之视图函数(views)

一个视图函数,简称视图,是一个简单的Python 函数,它接受Web请求并且返回Web响应。响应可以是一张网页的HTML内容,一个重定向,一个404错误,一个XML文档,或者一张图片. . . 是任何东西都可以。无论视图本身包含什么逻辑,都要返回响应。代码写在哪里也无所谓,只要它在你的Python目录下面。除此之外没有更多的要求了——可以说“没有什么神奇的地方”。为了将代码放在某处,约定是将视图放置在项目或应用程序目录中的名为views.py的文件中。

视图函数:     一定包含两个对象:         requset---->用户请求相关的所有信息(对象)         Httpresponse---->响应字符串

一个简单的视图

下面是一个返回当前日期和时间作为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对象。

视图函数,围绕着两个对象进行:HttpResponse和HttpRequest

1.HttpRequest

  request---->请求信息

属性:

request.path       # 获取访问文件路径

request.method属性   #获取请求中使用的HTTP方式(POST/GET)

request.body      #含所有请求体信息 是bytes类型

request.GET        #GET请求的数据(类字典对象)  请求头中的url中?后面拿值

方法:

1

get_full_path()

注意:键值对的值是多个的时候,比如checkbox类型的input标签,select标签,需要用:

1

request.POST.getlist("hobby")

2.HttpResponse

  HttpResponse---->相应字符串

对于HttpRequest请求对象来说,是由django自动创建的,但是,HttpResponse响应对象就必须我们自己创建。每个view请求处理方法必须返回一个HttpResponse响应对象。HttpResponse类在django.http.HttpResponse。

在HttpResponse对象上扩展的常用方法

 1.render 函数

将指定页面渲染后返回给浏览器

render(request, template_name[, context])

结合一个给定的模板和一个给定的上下文字典,并返回一个渲染后的 HttpResponse 对象。

参数:
     request: 用于生成响应的请求对象。

     template_name:要使用的模板的完整名称,可选的参数

     context:添加到模板上下文的一个字典。默认是一个空字典。如果字典中的某个值是可调用的,视图将在渲染模板之前调用它。

     content_type:生成的文档要使用的MIME类型。默认为DEFAULT_CONTENT_TYPE 设置的值。

     status:响应的状态码。默认为200。
from django.shortcuts import render

def test(request):
    return render(request,'index.html')   #向用户显示一个html页面

下面为render官方源码,可以看出render最后也是返回了一个HttpResponse给webserver

def render(request, template_name, context=None, content_type=None, status=None, using=None):
    """
    Returns a HttpResponse whose content is filled with the result of calling
    django.template.loader.render_to_string() with the passed arguments.
    """
    content = loader.render_to_string(template_name, context, request, using=using)
    return HttpResponse(content, content_type, status)

细说render:

  render方法主要是将从服务器提取的数据,填充到模板中,然后将渲染后的html静态文件返回给浏览器。这里一定要注意:render渲染的是模板,下面我们看看什么叫作模板:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <style>
        li,ul,ol{  list-style: none;  }
        a{ text-decoration: none; }
    </style>
</head>
<body>
<ul>
    {% for book in list %}
        <li><a href="{{book.id}}">{{ book.btitle }}</a></li>
    {% endfor %}
</ul>
</body>
</html>

上面{%%}之间包括的就是我们要从数据库取出的数据,进行填充。对于这样一个没有填充数据的html文件,浏览器是不能进行渲染的,所以,对于上述{%%}之间的内容先要被render进行渲染之后,才能发送给浏览器。

  下面举个例子:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Title</title>
    <style>
        li,ul,ol{  list-style: none;  }
        a{ text-decoration: none; }
    </style>
</head>
<body>
<ul>
    {% for book in list %}
        <li><a href="{{book.id}}">{{ book.btitle }}</a></li>
    {% endfor %}

</ul>
</body>
</html>
def show(request, id):  
    book = BookInfo.objects.get(pk=id)   #从数据库中取出对应id的数据
    herolist = book.heroinfo_set.all()  
    context = {'list': herolist}       # 将数据保存在list
    return render(request, 'booktest/show.html', context) #通过render进行模板渲染

 2.redirect 函数

参数可以是:

  • 一个模型:将调用模型的get_absolute_url() 函数
  • 一个视图,可以带有参数:将使用urlresolvers.reverse 来反向解析名称
  • 一个绝对的或相对的URL,将原封不动的作为重定向的位置。

默认返回一个临时的重定向;传递permanent=True 可以返回一个永久的重定向。

示例:

你可以用多种方式使用redirect() 函数。

传递一个对象

将调用get_absolute_url() 方法来获取重定向的URL:

1 2 3 4 5 6

from django.shortcuts import redirect   def my_view(request):     ...     object = MyModel.objects.get(...)     return redirect(object)

传递一个视图的名称

可以带有位置参数和关键字参数;将使用reverse() 方法反向解析URL: 

1 2 3

def my_view(request):     ...     return redirect('some-view-name', foo='bar')

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

1 2 3

def my_view(request):     ...     return redirect('/some/url/')

也可以是一个完整的URL:

1 2 3

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

默认情况下,redirect() 返回一个临时重定向。以上所有的形式都接收一个permanent 参数;如果设置为True,将返回一个永久的重定向:

1 2 3 4

def my_view(request):     ...     object = MyModel.objects.get(...)     return redirect(object, permanent=True)

跳转(重定向)应用

-----------------------------------url.py

 url(r"login",   views.login),
 url(r"yuan_back",   views.yuan_back),

-----------------------------------views.py
def login(req):
    if req.method=="POST":
        if 1:
            # return redirect("/yuan_back/")
            name="yuanhao"

            return render(req,"my backend.html",locals())

    return render(req,"login.html",locals())


def yuan_back(req):

    name="苑昊"

    return render(req,"my backend.html",locals())

-----------------------------------login.html

<form action="/login/" method="post">
    <p>姓名<input type="text" name="username"></p>
    <p>性别<input type="text" name="sex"></p>
    <p>邮箱<input type="text" name="email"></p>
    <p><input type="submit" value="submit"></p>
</form>
-----------------------------------my backend.html
<h1>用户{{ name }}你好</h1>

下面我们来看一个现象:

--------------------urls.py------------------------------

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^login/', views.login),
    url(r'^index/', views.index,),
    # url(r'^register/', views.register,name='reg'),

]

------------------view.py-------------------------------
def login(request):
    if request.method=='POST':
        username=request.POST.get('user')
        password=request.POST.get('pwd')
        if username=='yuan' and password=='123':
            # return render(request,'index.html')
            return redirect('/index/')
        else:
            return render(request,'login.html',{'info':'账号或密码错误'})
    else:
        return render(request,'login.html')


def index(request):
        name='yuan'
        return render(request,'index.html',{'a':name})

---------------login.html--------------------------------
<h1>登陆界面</h1>
<form action="/login/" method="post">
    <p>姓名 <input type="text" name="user"></p>
    <p>密码 <input type="password" name="pwd"></p>
    <p><input type="submit"></p>
    <p>{{ info }}</p>
</form>


---------------login.html--------------------------------
<h1>个人主页</h1>
<h2>hello,{{ a}}</h2>

首先,启动服务器后,我们进入login页面

正确输入姓名,密码后,此时执行redirect函数,结果如下

现在我们将redirect换成render,再重新走一遍看看,在login页面,正确输入姓名,密码后,结果如下:

细心的人会发现,用render函数执行后的,地址栏的地址没有变化,还是login,且页面上的{{a}}此时也没有被渲染,所以hello,后面没有内容显示!

对比render与redirect:

原因是         render: 只是返回页面内容,但是未发送第二次请求         redirect:发送了第二次请求,url更新

总结两者区别:    

     第一,render返回一个登陆成功后的页面,刷新该页面将回复到跳转前页面。而redirect则不会

       第二,如果页面需要模板语言渲染,需要的将数据库的数据加载到html,那么render方法则不会显示这一部分,render返回一个登陆成功页面,不会经过url路由分发系统,也就是说,不会执行跳转后url的视图函数。这样,返回的页面渲染不成功;而redirect是跳转到指定页面,当登陆成功后,会在url路由系统进行匹配,如果有存在的映射函数,就会执行对应的映射函数。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

package exec

exec包执行外部命令。它包装了os.StartProcess函数以便更容易的修正输入和输出,使用管道连接I/O,以及作其它的一些调整。

984
来自专栏企鹅号快讯

讲义15:服务器端编程:Request&Response

一、内容提要 B/S模型 Reponse对象 Request 对象 二、内容及操作步骤 1. B/S模型 Browser: 浏览器 Server: Web 服务...

2106
来自专栏风中追风

java类的加载过程和类加载器的分析

我们知道,我们写的java代码保存的格式是 .java, java文件被编译后会转换为字节码,字节码可以在任何平台通过java虚拟机来运行,这也是java能够跨...

5558
来自专栏Danny的专栏

ASP.NET中利用Application和Session统计在线人数、历史访问量

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/huyuyang6688/article/...

2773
来自专栏游戏杂谈

Lua调用C++时打印堆栈信息

公司的手游项目,使用的是基于cocos2d-x绑lua的解决方案(参数quick-x的绑定),虽然使用了lua进行开发,更新很爽了,但是崩溃依然较为严重,从后台...

2112
来自专栏技术博客

ExtJs五(ExtJs Mvc登录优化)

继上一节中简单的实现了登录之后http://www.cnblogs.com/aehyok/archive/2013/04/20/3033296.html,现在我...

1262
来自专栏大内老A

ASP.NET Core真实管道详解[2]:Server是如何完成针对请求的监听、接收与响应的【上】

Server是ASP .NET Core管道的第一个节点,负责完整请求的监听和接收,最终对请求的响应同样也由它完成。Server是我们对所有实现了IServer...

3645
来自专栏跟着阿笨一起玩NET

我的WCF之旅(1):创建一个简单的WCF程序

为了使读者对基于WCF的编程模型有一个直观的映像,我将带领读者一步一步地创建一个完整的WCF应用。本应用功能虽然简单,但它涵盖了一个完整WCF应用的基本结构。对...

731
来自专栏Python研发

Django之Cookie

在浏览器端(客户端)保存的键值对,特性:每次http请求都会携带.           举个例子:{"name":身份证号}

2313
来自专栏有趣的django

redis的使用 一、简介二、对redis的操作三、RDB和AOF的两种数据持久化机制四、设置redis的连接密码五、python操作redis

     redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)...

1363

扫码关注云+社区

领取腾讯云代金券