一.Django的视图函数view

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

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

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

  一个简单的视图

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

  1. from django.http import HttpResponse
  2. import datetime
  3.  
  4. def current_datetime(request):
  5. now = datetime.datetime(request):
  6. html = "<html><body>It is now %s.</body></html>" % now
  7. return HttpResponse(html)

  代码的逐行解释:

1)首先从django.http模块导入HyypResponse类,以及Python的datetime库

2)接着定义了current_datetime函数.它就是视图函数.每个视图函数都使用HttpResponse对象作为第一个参数,并且通常称为request.

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

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

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

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

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

  views.py(视图层),熟练掌握两个对象:请求对象(request)和响应对象(HTTPResponse)

二.CBV和FBV

  FBV(function base views)  就是在视图中使用函数处理请求

  CBV(class base views)  就是在视图里使用类处理请求

  Python是一个面向对象的编程语言,如果只用函数来开发,有很多面向对象的优点就错失了(继承,封装,多态).所以Django在后来加入了Class-Based-VieW.可以让我们用类写view.

  优点:

  1.提高代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)

  2.可以用不同的函数针对不同的HTTp方法处理,而不是通过很对if判断,提高代码的可读性

    如果我们要写一个处理GET方法的view,用函数写的话是下面这样

  1. from django.http import HttpResponse
  2.  
  3. def my_view(request):
  4. if request.method == 'GET':
  5. return HttpResponse('OK')

  如果用class-based-view写的话,就是下面:

  1. from django.http import HttpResponse
  2. from django.views import View
  3.  
  4. class MyView(View):
  5. def get(self,request):
  6. return HttpRsponse('ok')

  Django的URL 是将一个请求分配给可调用函数的,而不是一个class.针对这个问题,class-based view提供了一个as_view()静态方法(也就是类方法),调用这个类方法,会创建一个类的实例,然后通过这个实例调用dispatch()方法,dispath()方法会根据request的method的不同调用相应的方法来处理request(如get(),或者post()),到这里,这些方法和function-based-view差不多了,要接收request,得到了一个response返回.返回方法没有定义,会抛出HttpResponseNotAllowed异常。

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

  1. # urls.py
  2. from django.conf.urls import url
  3. from myapp.views import MyView #引入我们在views.py里面创建的类
  4.  
  5. urlpatterns = [
  6. url(r'^index/$', MyView.as_view()),
  7. ]

  CBV传参,和FBV类似,有名分组,无名分组

  url写法:无名分组的

  1. url(r'^cv/(\d{2})/', views.Myd.as_view(),name='cv'),
  2. url(r'^cv/(?P<n>\d{2})/', views.Myd.as_view(name='xxx'),name='cv'),
    #如果想给类的name属性赋值,前提你的Myd类里面必须有name属性(类属性,
    定义init方法来接受属性行不通,但是可以自行研究一下,看看如何行通,意义不大),
    并且之前类里面的name属性的值会被覆盖掉

  类写法:

  1. class Myd(View):
  2. name = 'sb'
  3.  
  4. def get(self,request,n):
  5. print('get方法执行了')
  6. print('>>>',n)
  7. return render(request,'cvpost.html',{'name':self.name})
  8.  
  9. def post(self,request,n):
  10. print('post方法被执行了')
  11. return HttpResponse('post')

 四.给视图加装饰器

  使用装饰器装饰FBV

  FBV本身就是一个函数,就是Python通用装饰器的加法.

  1. def wrapper(func):
  2. def inner(*args,**kwargs):
  3. start_time = time.time()
  4. ret = func(*args,**kwargs)
  5. end_time = time.time()
  6. print("used:",end_time - start_time)
  7. return ret
  8. return inner
  9.  
  10. #FBV版本添加班级
  11. @wrapper
  12. def add_class(request):
  13. if request.method == "POST":
  14. class_name = request.POST.get("calss_name")
  15. models.Classes.objects.create(name=class_name)
  16. return redirect("/class_list/")
  17. return render(request,"add_class.heml")

  使用装饰器装饰CBV

  类中的方法与独立函数不完全相同,因此不能直接将函数装饰器应用于类中的方法 ,我们需要先将其转换为方法装饰器。

  Django中提供了method_decorator装饰器用于将函数装饰器转换为方法装饰器。

  1. from django.views import View
  2. from django.utils.decorators import method_decorator
  3.  
  4. class AddClass(View):
  5.  
  6. @method_decorator(wrapper)
  7. def get(self, request):
  8. return render(request, "add_class.html")
  9.  
  10. def post(self, request):
  11. class_name = request.POST.get("class_name")
  12. models.Classes.objects.create(name=class_name)
  13. return redirect("/class_list/")

五.request对象

  当一个页面被请求时,Django就会创建一个包含本次请求原信息(请求报文中的请求行、首部信息、内容主体等)的HttpRequest对象。

  Django会将这个对象自动传递给响应的视图函数,一般视图函数约定俗成的使用request参数承接这个对象.

  Django会将这个对象自动传递给相应的视图函数,一般视图函数约定俗成的使用request参数承接这个对象.

  请求相关的常用值

1)path_info   返回用户访问URL,不包括域名

2)method      请求中使用的HTTP方法的字符串表示,全大写表示.

3)get              包含所有Http GET参数的类字典对象

4)post             包含所有HTTP POST参数类字典对象

5)body     请求体,byte类型 request.POST的数据就是从body里面提取到的

  要处理表单数据的时候,推荐还是使用HttpRequest.POST.

  另外,我们还可以用Python的类文件方法去操作它.

2.HttpRequest.path

  1.   一个字符串,表示请求的路径组件(不含域名)。
  2.   例如:"/music/bands/the_beatles/"
  3. 3.HttpRequest.method
  4.   一个字符串,表示请求使用的HTTP 方法。必须使用大写。
  5.   例如:"GET""POST"

 六.响应  response

  响应对象有三种形式:

  (1) HTTPResponse()

  (2) render()

  (3)redirect()

  HTTPResponse()括号内直接跟一个具体的字符串作为响应体,比较直接很简单.

  Django shortcut function

    render()

    

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

      参数:

        request: 用于生成相应的请求对象.

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

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

  例子:

  1. from django.shortcuts import render
  2.  
  3. def my_view(request):
  4. # 视图的代码写在这里
  5. return render(request, 'myapp/index.html', {'foo': 'bar'})

   redirect():给浏览器了一个30x的状态码

    参数是:

      1/ 一个模型,将调用模型的get_absolute_url() 函数

      2/ 一个视图,可以带有参数:将使用urlresolvers.revese来反向解析名称

      3/一个绝对的或相对的URL,将原封不动的作为重定向的位置

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

    示例:

    可以用多种方法使用redirect()函数.

    传递一个视图的名称

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

    传递要重定向到的一个具体的网址

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

    看一个例子

        index.html文件,内容如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8. <div>这是index页面</div>
  9. <h1>{{ name }}</h1>
  10.  
  11. </body>
  12. </html>

        login.html文件,内容如下

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>Title</title>
  6. </head>
  7. <body>
  8.  
  9. <div>
  10. <form action="{% url 'xxx' %}" method="post">
  11. 用户名:<input type="text" name="username">
  12. 密码:<input type="password" name="password">
  13. <input type="submit">
  14. </form>
  15.  
  16. </div>
  17.  
  18. </body>
  19. </html>

        urls.py里面的内容:

  1. from django.shortcuts import render,HttpResponse,redirect
  2.  
  3. def index(request):
  4. return render(request,'index.html',{'name':'ce'})
  5.  
  6. def login(request):
  7. method = request.method
  8.  
  9. if method == 'GET':
  10. return render(request,'login.html')
  11. else:
  12. username = request.POST.get('username')
  13. password = request.POST.get('password')
  14. if username == 'ce' and password == '123':
  15. return redirect('/index/') #重新定向到/index/路径,这也是发送了一个请求,
    别忘了在上面引入这个redirect类,和render,HttpResponse在同一个地方引入
  16. else:
  17. return HttpResponse('失败')

    上面几个文件搞好之后,我们重启Django项目,然后登陆页面的输入网址,注意,你输入的网址端口要和你启动的django项目的端口一样。

  但是如果我们在函数里面写的render来返回内容,两者有什么不同呢?

  1. from django.shortcuts import render,HttpResponse,redirect
  2.  
  3. # Create your views here.
  4.  
  5. def index(request):
  6.  
  7. return render(request,'index.html',{'name':'chao'})
  8.  
  9. def login(request):
  10. method = request.method
  11.  
  12. if method == 'GET':
  13. return render(request,'login.html')
  14. else:
  15. username = request.POST.get('username')
  16. password = request.POST.get('password')
  17. if username == 'chao' and password == '123':
  18. return redirect('/index/') #重定向到/index/路径,这也是发送一个请求,别忘了在上面引入这个redirect类,和render,HTTPResponse在一个地方引入
  19. #如果直接用render来返回页面,是一次响应就返回来页面,两者是有区别的,如果你用render返回index.html页面,那么这个页面里面的模板渲染语言里面需要的数据你怎么搞,如果这些数据就是人家index那个函数里面独有的呢,你怎么搞,有人可能就响了,我把所有的数据都拿过来不就行了吗,首先如果数据量很大的话,是不是都重复了,并且你想想如果用户登陆完成之后,你们有进行跳转,那么如果网速不太好,卡一下,你想刷新一下你的页面,你是不是相当于又发送了一个login请求,你刷新完之后,是不是还要让你输入用户名和密码,你想想是不是,所有咱们一般在登陆之后都做跳转。
  20. #redirect本质上也是一个HttpResponse的操作,看看源码就知道了
  21. # return HttpResponse('success')
  22. else:
  23. return HttpResponse('失败')

03 Django之视图函数的更多相关文章

  1. Django之视图函数总结

    Django之视图函数总结 HttpRequest与HttpResponse http请求中产生两个核心对象: HttpRequest对象:用户请求相关的所有信息(对象) HttpResponse对象 ...

  2. django views视图函数返回值 return redirect httpresponse总结

    django views视图函数返回值 return redirect  render httpresponse总结

  3. Django 定义视图函数

    Django 定义视图函数 一.接收内容及文件处理 1.接收分类 # 获取数据 request.GET # 提交数据 request.POST # 获取文件 request.FILES 2.check ...

  4. django的视图函数

    一.视图函数view 视图函数是接收一个请求(request对象),并返回响应的函数 1. HttpResponse响应请求 这个方法是返回字符串一类的,可以识别标签 2. render响应请求 re ...

  5. Django restframe 视图函数以及ModelSerializer的使用

    建立model数据库 from django.db import models __all__ = ['Book', 'Publisher', 'Author'] # Create your mode ...

  6. Django的视图函数和路由系统中一些没有用过的小点

    1.request对象 print("返回用户访问的url,但是不包括域名",request.path_info) print("返回请求的方法,全大写",re ...

  7. django views视图函数

    Django views.py视图文件 一. 创建views.py文件,在工程文件夹根目录创建views.py视图文件,其实任意文件名都可以,使用views是为了遵循传统. 注:所有的views函数都 ...

  8. Django中非视图函数获取用户对象

    今天遇到了一个问题:在Django中怎么从非视图函数中获取用户对象?怎么保证不同的请求获取到不同的用户对象? 平常我们获取用户对象使用的是: request.user 不得不说,这确实很方便. 但是, ...

  9. django中视图函数的FBV和CBV

    1.什么是FBV和CBV FBV是指视图函数以普通函数的形式:CBV是指视图函数以类的方式. 2.普通FBV形式 def index(request): return HttpResponse('in ...

随机推荐

  1. PHP中的符号 ->、=> 和 :: 分别表示什么意思?

    php新手经常碰到的问题,->.=> 和 :: 这三个家伙是什么分别都是做什么的啊!看着就很晕. 没关系,下面我们做一下详细的解释,如果你有C++,Perl基础,你会发现这些家伙和他们里面 ...

  2. IDEA 不编译java以外的文件

    解决办法:修改pom 文件 <build> <resources> <resource> <directory>src/main/java</di ...

  3. ARM 之一 ELF文件、镜像(Image)文件、可执行文件、对象文件 详解

    [转]https://blog.csdn.net/ZCShouCSDN/article/details/100048461 ELF 文件规范   ELF(Executable and Linking ...

  4. Centos7安装php5.6并配置php-fpm协同工作

    yum install epel-release rpm -ivh http://rpms.famillecollet.com/enterprise/remi-release-7.rpm yum in ...

  5. Laravel用户认证系统的实现细节

    原文地址:http://www.php.cn/php-weizijiaocheng-406076.html 这篇文章主要介绍了关于Laravel用户认证系统的实现细节,有着一定的参考价值,现在分享给大 ...

  6. 基于Spring Boot的可直接运行的分布式ID生成器的实现以及SnowFlake算法详解

    背景 最近对snowflake比较感兴趣,就看了一些分布式唯一ID生成器(发号器)的开源项目的源码,例如百度的uid-generator,美团的leaf.大致看了一遍后感觉uid-generator代 ...

  7. hdu 1106

    排序 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submissi ...

  8. vue A对象赋值给B对象,修改B属性会影响到A问题

    实际在vue中  this.A = this.B,没有进行深层赋值,只是把this.A的地址指向了与this.B相同的地址,所有对于A的修改会影响到B. 解决相互影响的思路是在this.A必须是新建的 ...

  9. Linux 时间以及时间间隔的简单处理.

    最近想知道自己的一个部署脚本的耗时, 中午时间看了一下最简单的Linux 时间函数的处理 我这里的处理非常简单, 仅仅是够用而已. 处理过程. 1. 获取当前时间: time1=`date` 或者是 ...

  10. 路由 router-view

    路由,其实就是指向的意思,当我点击页面上的home按钮时,页面中就要显示home的内容,如果点击页面上的about 按钮,页面中就要显示about 的内容.Home按钮 => home 内容, ...