Django视图层的扩展

什么是视图

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

视图的作用

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

视图的本质

视图就是一个Python中的函数

视图的响应:

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

json数据

视图的调用过程

image

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'
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容