Django视图层的扩展

什么是视图

视图是通过对模型的操作,从模型中取出数据并返回给模板的Python函数。

视图的作用

视图接受web请求,并响应web请求

视图的本质

视图就是一个Python中的函数

视图的响应:

网页:重定向;错误视图(404,500)

json数据

视图的调用过程

url配置

在创建完Django工程之后,在工程的settings.py文件中已经配置过根级url配置文件的位置了。

ROOT_URLCONF = 'djangoProject.urls'

以上配置就是settings.py文件中默认配置好的根级url,格式为:工程名.url配置文件的名称。我们可以随便命名只需要对应的创建出来就可以。但一般情况下,我们按照默认的情况即可。

因此,我们所有的url都会被配置到这个urls.py文件中。下面我们解释一下这个文件中的内容。

"""silva URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  url(r'^$', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  url(r'^$', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.conf.urls import url, include
    2. Add a URL to urlpatterns:  url(r'^blog/', include('blog.urls'))
"""
from django.conf.urls import url
from django.contrib import admin


urlpatterns = [
    url(r'^admin/', admin.site.urls),
]

我们可以看到这个文件中主要就有一个配置项,urlpatterns(一个url实例的列表)。配置中的url()函数就是我们以后配置的url。

Django的 url() 可以接收四个参数,分别是两个必选参数:regex、view 和两个可选参数:kwargs、name,接下来详细介绍这四个参数。

# regex: 正则表达式,与之匹配的 URL 会执行对应的第二个参数 view。
# view: 用于执行与正则表达式匹配的 URL 请求。
# kwargs: 视图使用的字典类型的参数。
# name: 用来反向获取 URL(在后面会做详细说明)。

url匹配正则的注意事项:

  •  如果想要从url中获取一个值,需要对正则加小括号
  •  匹配正则前方不需要加反斜杠
  •  正则前需要加r表示字符串不转义

引入其他url配置

对于一个企业级的项目来说,会有数百个url,如果都写在一个文件中维护起来实在是不方便,而且在一个团队中大家都修改这一个文件经常会出现冲突,显然是不合理的。因此,就应该有将url分开管理的需求。下面我们说一下如何分开管理url。

在每一个应用(app)中创建各自的urls.py文件,改文件的格式和根级urls.py文件相同,在该文件中定义本应用(app)的url配置,在工程的根级urls.py文件中使用include()方法将每一个应用(app)的urls.py文件引入进来即可。

from django.conf.urls import include

urls(r’^任意的url前缀’,include(‘app_name.urls’),namespace=’定义任意的名称空间’)

namespace是用来做反向解析的,如果不使用反向解析,我们完全可以不用定义。

url的反向解析

如果我们所有的url都是写死的,假设我在根级目录中修改了url,那么我们所有的引入都将修改,这样的工作量很大,这样,namespace就有用了,对应的app的urls.py文件中的url只需要指定name就可以了

url(r’^index’,’views.index’, name=’给这个url定义一个任意的名称’)

解决思路:在使用链接时,通过根级url配置的名称空间和app中的url中配置的名称,动态生成url地址

视图函数

 视图函数本质就是一个Python函数,只是传递了一个HttpRequest的一个实例参数。

定义视图

视图函数是在每一个app下的views.py文件中定义的。格式如下:

def index(request):
    title = "欢迎学习django"
    lists = [1, 2, 3]
    return render(request, 'userInfo\\add_user.html', {'title': title, 'list': lists})

通过render函数将我们处理后的数据返回给前台的视图。render的第一个参数是request,第二个参数是对应的模板的路径,第三个参数是要传递给前台的数据,以dict形式传递。

错误视图

   404视图:找不到网页(url匹配不成功)时返回;在templates目录下定义404.html

        <h2><{{request_path}}/h2> # 导致错误的网址

        配置settings.py中的DEBUG = False和ALLOWED_HOSTS = [‘*’]

       如果DEBUG为True永远不会调用404.html

500视图:在视图代码中出现错误(服务器代码)

400视图:错误出现在客户的操作

HttpRequest对象

服务器接收http请求后,会根据报文创建HttpRequest对象。视图中的第一个参数就是HttpRequest对象,浏览器中传过来的参数都在request对象参数中,Django创建的,之后调用视图方法时传递给视图

HttpRequest的属性:

         path:请求的完整路径(不包括域名和端口,包含参数)

         method:表示请求的方式,常用的有GET,POST

         encoding:表示浏览器提交的数据的编码方式,一般为utf-8

         GET:类似于字典的对象,包含了get请求的素哟有参数

         POST:类似于字典的对象,包含了POST请求的所有参数

         FILES:类似于字典的对象,包含了所有上传的文件

         COOKIES:就是字典,包含所有的cookie

         session:类似字典的对象,表示当前会话

HttpRequest的方法:

         is_ajax():如果是通过XMLHttpRequest发起的。

         QueryDict:

                   eequest对象中的GET、POST都属于QueryDict对象

                   方法:

                            get():根据键获取值,只能获取一个值url?a=3&b=4

                            getlist():将键的值以列表的形式返回,可以获取多个值url?a=3&a=4

         GET:用浏览器传递的数据

                   获取GET传递的数据,url传递参数

                  def get1(request):

                            a = request.GET.get(‘a’)

                            b = request.GET.get(‘b’)

                            c = reqeust.GET.get(‘c’)

                            return HttpResponse(a + ‘ ‘ + b + ‘ ‘ + c)

                   def get2(request):

                            a = request.GET.getlist(‘a’)

                            a1=  a[0]

                            a2 = a[1]

                            c = request.GET.getlist[‘c’]

                            return HttpResponse(a1 + ‘ ‘ + a2 + ‘ ‘ + c)

         POST

                   使用表单提交实现POST请求

                   def showregister(request):

                            return render(request,’app/regist.html’)

                   def regist(request):

                            name = request.POST.get(‘name’)

                            hobby = request.POST.getlist(‘hobby’)

                            return HttpResponse(‘post’)

                   # 关闭csrf,在settings.py中注释掉csrf的中间件

HttpResponse对象

给浏览器返回数据, HttpRequest对象是由Django创建的,HttpResponse对象使用程序员创建的

用法:

      不调用模板,直接返回数据 HttpResponse(data)

      调用模板

      使用render方法:

            原型:render(request,templateName[,context])

            作用:结合数据和模板,返回一个完整的HTML页面

            参数:

                   request:请求体对象

                   templateName:模板路径

                   context:传递给需要渲染在模板上的数据

             示例:

                   return render(request,’app_name/login.html’)

HttpResponse对象属性:

           content:返回的内容的内容

           charset:编码格式

           status_code:相应状态码(200,304,404,400,500)

           content-type:指定输出的MIME类型          

def showresponse(request):
    res = HttpResponse()
    res.content = b’good’
    print(Res.context)
    print(res.charset)
    print(res.status_code)
    print(res,content-type)
    return res

HttpResponse对象方法:

          init:使用页面的内容实例化HttpResponse对象

          write(content):以文件的形式写入

          flush():以文件的形式输出

          set_cookie(key,value=’’,max_age=None,exprise=None):设置cookie

          delete_cookie(key):删除cookie,注意,如果删除不存在的cookie,就当什么都没发生。

验证cookie

def cookieCheck(request):
    res = HttpResponse()
    cookie = request.COOKIES
    res.write(‘<h2>’+cookie[‘name’]+’</h2>’)
    res.set_cookie(‘name’,’good’)
    return res

子类HttpResponseRedirect

功能:重定向,服务器端的跳转             

from django.http import HttpResponseRedirect

def redirect1(request):
    return HttpResonpseRedirect(‘/sunck/redirect2’)

def redirect2(request):
    return HttpResponse(‘redirect’)

# 可以简写:redirect
from django.shortcuts inmport import redirect
def redirect3(request):
    return redirect(‘redirect2’)

# 推荐使用反向解析

子类JsonResponse

          可以返回json数据,一般用于异步请求。__init__(self,data),data是字典对象

from django.http import JsonResponse

def jsonresponse(request):
      if request.is_ajax():
            a = JsonResponse({})
      return a

       注意:content-type类型是application/json

状态保持

http协议是无状态的,每次请求都是新的请求,不记得以前的请求。 客户端与服务器端的一次通信就是一次会话, 实现状态保持,在客户端或者服务端存储有关会话的数据

存储方式:cookie(所有的数据存储在客户端,不要存储敏感的数据),session(所有的数据存储在服务端,在客户端用cookie存储session_id)

状态保持的目的:在一段时间内跟踪请求者的状态,可以实现跨页面访问当前的请求者的数据。

注意:不同的请求者之间不会共享这个数据。与请求者是一一对应的。

启用session:settings.py文件中的INSTALL_APP中配置,默认是启用的,还要启用session中间件。

使用session:启用session后每个HttpRequest对象都有一个session属性,就是一个类似字典的对象

           get(key,default=None) 根据键获取session值

           clear() 清空所有的会话

           flush()删除当前的会话,并删除会话的cookie

def main(request):
    # 去session
    username = request.session.get('name','游客')
    print(username)
    return render(request,'myApp/main.html',{'username':username})

def login(request):
    return render(request,'myApp/login.html')

def showmain(request):
    print('adfgfdg')
    # username = request.POST.get('username')
    # 存储session
    # request,session['name'] = username
    return redirect('/app/main/')

from django.contrib.auth import logout
def quit(request):
    # 清除session
    logout(request)
    # request.session.clear()
    # request.session.flush()
    return redirect('/app/main')

url(r'^main/$', views.main),
url(r'^login/$', views.login),
url(r'^showmain/$', views.showmain),

设置过期时间:set_expiry(value);如果不设置,两个星期后过期,value是一个整数,以秒为单位

        request.session.set_expiry(10)

        也可以是一个时间对象

        也可以是0:关闭浏览器时失效

        None是永不过期

存储session的位置

数据库

默认存储在数据库中:

SESSION_ENGINE = ''django.contrib.sessions.backends.db'

缓存

只存储在本地内存中,如果丢失不能找回,比数据库快

SESSION_ENGINE = ‘django.contrib.sessions.backends.cache’

数据库和缓存

SESSION_ENGINE =  'django.contrib.sessions.backends.cached_db'

使用redis缓存session

1、pip install django-redis-sessions

2、添加以下配置

SESSION_ENGINE = 'redis_sessions.session'
SESSION_REDIS_HOST = 'localhost'
SESSION_REDIS_PORT = 6379
SESSION_REDIS_DB = 0
SESSION_REDIS_PASSWORD = '123456'
SESSION_REDIS_PREFIX = 'session'

猜你喜欢

转载自my.oschina.net/epoch/blog/1797504