django学习第十三天

Posted weiweivip666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了django学习第十三天相关的知识,希望对你有一定的参考价值。

jquery操作cookie

  • 下载地址
      http://plugins.jquery.com/cookie/
  • 引入
      <script type="text/javascript" src="js/jquery.min.js"></script>
      <script type="text/javascript" src="js/jquery.cookie.js"></script>
  • cookie操作
      设置值:
      $.cookie(‘the_cookie‘,‘the_value‘);
      #设置7天有效期
      $.cookie(‘the_cookie‘,‘the_value‘,{expires:7});
      
      读取
      $.cookie(‘the_cookie‘); #通过键来取值

      删除cookie
      $.cookie(‘the_cookie‘,null); #通过传递null作为cookie的值即可

中间件

配置文件

      项目主目录中的配置文件是django留给开发者使用的用户级别配置文件
      实际上django有一个自己的默认全局配置文件
      那么他们的关系如下

      #django默认配置
      from django.conf import global_settings

      #用户级别配置
      from django_middleware import settinigs

      from django.conf import settings  #中间人
      #比如需要引入配置中的某个配置项settings.APPEND_SLASH,那么这样的引入的查找顺序是这样的,先去用户级别settings.py文件中找这个配置,如果没有找到,那么再去global_settings中去找默认配置

django请求生命周期

技术图片

      中间件用来对请求和响应做一些统一加工和处理的,比如对所有请求中的post请求做一个csrftoken认证,就用到了我们的‘django.middleware.csrf.CsrfViewMiddleware‘,后面视图中能够使用request.session做一个session相关操作,这个request.session的功能就是在这个中间件中加工好的‘django.contrib.sessions.middleware.SessionMiddleware‘

自定义中间件

  • 登录认证、权限认证、频率访问限制、请求数据统计等等...
  • 自定义中间的步骤
      1.应用文件夹下面创建一个文件夹,名字随便起,比如叫作mymiddleware
      2.在mymiddleware文件夹下面创建一个py文件,名称随意,比如叫做middlewares.py
      3.在middlewares.py文件中写上如下内容

      from django.utils.deprecation import MiddlewareMixin
      class LoginAuth(MiddlewareMixin):
            def process_request(self,request):
                  print(‘xxx‘)

      4.settings.py配置文件中写上如下内容
      MIDDLEWARE = [
            ....
            ‘应用名.中间文件夹.中间文件.类‘
            ‘app01.mymiddleware.middlewares.LoginAuth‘, #配置中间件类,告诉django,我写的这个自定义中间件,你帮我使用上,一般都是放到最后,不然上面几个中间件的相关功能就没办法使用上了。
            #如果中间件功能不想用了,就注释掉它就行了。
            #以上几步搞定后,所有请求都会触发我们的中间件类中的process_request方法。
            ]
  • 登录认证中间示例
      中间件代码如下
      #登录认证中间件
      class LoginAuth(MiddlewareMixin):
            #/login/登录请求,应该正常放行,让他能获得login.html页面
            #添加一个白名单,这样首页登录就不需要登录认证
            white_list = [‘/login/‘,]
            def process_request(self,request):
                  print(‘请求来啦!!!‘)
                  #获取当前请求路径:request.path /login/
                  #如果当前请求路径在白名单里面,我们不进行登录认证
                  if not request.path in self.white_list:
                        is_login = request.session.get(‘is_login‘) #True
                        if not is_login:
                              return redirect(‘/login/‘)


      #视图代码
      def login(request):
            if request.method == ‘GET‘:
                  return render(request,‘login.html‘)
            else:
                  #print(‘xxxxxx‘)
                  uname = request.POST.get(‘username‘)
                  if uname == ‘root‘:
                        request.session[‘is_login‘] = True
                        return redirect(‘/home/‘)#告诉浏览器向/home/发送get请求获取页面
                  else:
                        return redirect(‘/login/‘)

      def home(request):
            print(‘home‘)
            return render(request,‘home.html‘)

      def index(request):
            print(‘index‘)
            return render(request,‘index.html‘)

      #执行步骤:如判断用户访问home页面,是否已经登录过了
      第一次请求的时候,先是走的中间件process_request,login路径,在白名单里面,所以就不会走下面的判断,
      实际后面会有个return None,就表示是正常返回,可以省略不用写,然后再去执行视图逻辑,获取到login页面,
      然后发送post请求数据,又会走一遍process_request,正常返回后再去执行视图逻辑,后台获取发送来的数据,
      设置session,然后重定向到home页面。
      下次想直接访问home页面的时候,先是发送/home/请求,先走中间件process_request,判断当前的路径是不是在白名单里,
      显然不在,然后执行下面的逻辑代码,获取到session中的键值对,如获取到了,那么就return redirect(‘/home/‘)
      告诉浏览器向/home/发送get请求获取页面,然后再去执行后台视图逻辑中的代码

中间件的五个方法

整个中间件的执行顺序

技术图片

      process_request从上到下,process_response从下到上
  • 五个方法:process_request和process_response这个两个是重点
      process_request(self,request) #请求
      process_view(self,request,view_func,view_args,view_kwargs)#视图
      process_template_response(self,request,response)#模板
      process_exception(self,request,exception) #错误
      process_response(self,request,response) #响应

每个方法的执行流程

  • 1.process_request
      class Md1(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)
                  #当process_request返回时None,可以默认不写,那么才会继续执行后面的中间件的process_request,如果你是最后一个中间件,并且你返回的是None,那么逻辑会继续执行到我们的url路由控制器
                  #但是当process_request里面return的是一个HttpResponse对象,那么后面的中间件的process_request将不再执行,也不会走到url路由控制器
                  #return HttpResponse(‘中间件md1的逻辑,没有通过!!!‘)

      class Md2(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)


      views.py代码
      def home(request):
          print(‘home‘)
          return render(request,‘home.html‘)
      执行流程--中间件正常return None的情况:
            MD1--process_request
            MD2--process_request
            home
      
      执行流程--中间件Md1中响应回复对象的情况:
            MD1--process_request
      因为Md1中return的是响应对象,所以就不会再向下执行了,同时也不会去执行逻辑代码。
                 
  • 2.process_response
      class Md1(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)
            
            def process_response(self,request,response):
                  :param request:   当前请求对象
                  :param response:   视图函数的响应对象
                  :return:
                  print(‘Md1--响应‘)
                  #可以对响应内容做统一处理,如加响应头
                  response[‘xx‘] = ‘oo‘
                  print(response.content) #获取响应回复内容 #b‘ok‘
                  #注意,如果你写了process_response方法,那么这个方法必须return response
                  return response

      class Md2(MiddlewareMixin):
            def process_request(self,request,response):
                  print(‘MD2--process_request‘)
      
            def process_response(self,request,response):
                  print(‘MD2--响应‘)
                  # if response.content != b‘ok‘:
                        #如果process_response方法里面return了一个HttpResponse对象,那么这个对象会覆盖视图返回来的HttpResponse对象
                        #return HttpResponse(‘响应不OK!!!‘)
                  return response
      
      views.py文件
      def home(request):
            print(‘home‘)
            return render(request,‘home.html‘)
            #return HttpResponse(‘我是home响应‘)

      执行流程  正常执行:
      MD1--process_request  #中间件请求从上至下
      MD2--process_request
      home                  #请求结束会后执行视图逻辑
      MD2--process_response #中间响应从下至上
      MD1--process_response

      执行流程 中间件HttpResponse响应覆盖视图返回来的Httpresponse对象:
      MD1--process_request  #中间件请求从上至下
      MD2--process_request
      home                  #执行视图逻辑,响应我是home响应
      MD2--process_response #中间件响应从下至上,覆盖视图响应对象响应不OK!!!
      MD1--process_response

  • 注意事项
      当中间件1的process_request方法return的是一个HttpResponse,那么会执行中间件1的process_response方法,不会去执行中间件2的方法了

技术图片

  • 3.process_view(self,request,view_func,view_args,view_kwargs)
      from django.shortcuts import render,redirect,HttpResponse
      from django.utils.deprecation import MiddlewareMix
      
      class Md1(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)

            def process_response(self,request,response):
                  print(‘MD1--process_response‘)
                  return response

            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD1--process_view‘)

      class Md2(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD2--process_request‘)

            def process_response(self,request,response):
                  :param request:
                  :param view_func:   此次请求要执行的视图函数对象
                  :param view_args:  要函数的参数
                  :param view_kwargs: 要函数的参数
                  :return:
                  print(‘MD2--process_response‘)
                  return response

            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD2--process_view‘)


            执行流程:
            MD1--process_request  #中间件请求从上至下
            MD2--process_request
            MD1--process_view   #中间件视图从上至下
            MD2--process_view
            中间件2执行函数名称 home  
            home                 #逻辑视图
            MD2--process_response  #中间件响应 从下至上
            MD1--process_response
  • process_view图解
    技术图片
  • 4.process_exception(self,request,exception)
      当视图函数出现错误或者异常时,自动触发的方法,能够捕获视图出现的错误,进行一些错误的统一处理

      from django.shortcuts import render,redirect,HttpResponse
      from django.utils.deprecation import MiddlewareMixin

      class Md1(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)
                  
            def process_response(self,request,response):
                  print(‘MD1--process_response‘)
                  return response

            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD1--process_view‘)

            def process_exception(self,request,exception):
                  print(‘MD1--process_exception‘)

      class Md2(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD2--process_request‘)

            def process_response(self,request,response):
                  print(‘MD2--process_response‘)
                  return response

            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD2--process_view‘)
                  
            def process_exception(self,request,exception):
                  print(‘MD2--process_exception‘)

      views.py代码
      from django.core.exceptions import PermissionDenied #为了演示错误
      def home(request):
            print(‘home‘)
            raise PermissionDenied(‘权限不够‘)
            return render(request,‘home.html‘)

      执行流程:
      MD1--process_request #中间件请求从上至下
      MD2--process_request
      MD1--process_view   #中间件视图从上至下
      MD2--process_view
      home                #逻辑视图
      MD2--process_exception  #中间件错误从下至上
      MD1--process_exception
      MD2--process_response  #中间件响应从下至上
      MD1--process_response
  • process_exception图解
    技术图片

  • 5.process_template_response(self,request,reponse)

      from django.shortcuts import render,redirect,HttpResponse
      from django.utils.deprecation import MiddlewareMixin

      class Md1(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD1--process_request‘)

            def process_response(self,request,response):
                  print(‘MD1--process_response‘)
                  return response
      
            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD1--process_view‘)

            def process_exception(self,request,exception):
                  print(‘MD1--process_view‘)

            def process_template_response(self,request,response):
                  print(‘MD1--process_template_response‘)
                  return response

      class Md2(MiddlewareMixin):
            def process_request(self,request):
                  print(‘MD2--process_requeust‘)

            def process_response(self,request,response):
                  print(‘MD2--process_response‘)

            def process_view(self,request,view_func,view_args,view_kwargs):
                  print(‘MD2--process_view‘)

            def process_exception(self,request,exception):
                  print(‘MD2--process_exception‘)

            def process_template_response(self,request,response):
                  print(‘MD2--process_template_response‘)
                  return response

      views.py代码
      def home(request):
            print(‘home‘)
            def render():
                  print(‘你好render‘)
                  return HttpResponse(‘你好response‘)
            ret = HttpResponse(‘ojbk‘)
            #必须给HttpResponse对象封装一个render属性等于一个render函数,才能触发中间件里面的process_template_response方法
            ret.render = render
            return ret


      执行流程:
      MD1--process_request  #中间件请求从上至下
      MD2--process_request
      MD1--process_view      #中间件视图从上至下
      MD2--process_view
      home                  #视图逻辑
      MD2--process_template_response   #中间件模板 从下至上
      MD1--process_template_response
      你好render                  #视图逻辑里面的render()函数中响应对象
      MD2--process_response      #中间件响应 从下至上
      MD1--process_response

url路由系统补充---include路由分发和命名空间 namespace

  • 1.创建app
      python manage.py startapp app01
  • 2.配置app,在settings.py文件中
      INSTALLED_APPS = [
                  ...
                  ‘app02‘,
            ]

路由分发步骤

  • 1.在项目主目录下的urls.py(以后我们称之为总路由)文件中,写上如下内容
      from django.conf.urls import url,inclue
      from django.contrib import admin
      #路由分发功能
      urlpatterns = [
            url(r‘^admin/‘,admin.site.urls),
            url(r‘^app01/‘,include(‘app01.urls‘)),#include参数格式‘应用名称.urls‘
            url(r‘^app02/‘,include(‘appo2.urls‘)),
            #/app01/index/  先在总路由中匹配前面的路径,然后匹配到了,拿剩下的index/,去app01应用下面的urls.py文件进行路径匹配
      ]
  • 2.在每个应用文件夹下面创建一个ursl.py文件,里面内容
      from django.conf.urls import url,include
      from app01 import views
      urlpatterns = [
            url(r‘^index/‘,views.index),
      ]

问题,当两个应用中的url的别名相同了,使用反向解析的时候该怎么解决

      app01的urls.py
      from django.conf.urls import url,include
      from app01 import views
      urlpatterns = [
            url(r‘^index/‘,views.index),
            url(r‘^home/‘,views.home,name=‘home‘),
      ]

      app02下的urls.py
      from django.conf.urls import url,include
      from app02 import views
      urlpatterns = [
            url(r‘^index/‘,views.index),
            url(r‘^home/‘,views.home,name=‘home‘),
      ]

      app01的views.py文件进行别名解析
      def index(request):
            print(‘app01>>>‘,reverse(‘home‘))
            return HttpResponse(‘app01-index‘)

      app02的views.py文件进行别名解析
      def index(request):
            print(‘app02>>>‘,reverse(‘home‘))
            return HttpResponse(‘app02-index‘)

      以上执行完后,发现别名冲突,导致反向解析出错了

解决办法,用命名空间

      总路由写法
      from django.conf.urls import url,include
      from django.contrib import admin
      #路由分发
      urlpatterns = [
            url(r‘^app01/‘,include(‘app01.urls‘,namespace=‘app01‘)),
            url(r‘^app02/‘,include(‘app02.urls‘,namespace=‘app02‘)),
      ]

      app01视图写法
      def index(request):
            print(‘app01>>>‘,reverse(‘app01:home‘))
            return HttpResponse(‘app01-index‘)

      app02视图写法
      def index(request):
            print(‘app02>>‘,reverse(‘app02:home‘))
            return HttpResponse(‘app02-index‘)

      模板中使用
      {% url ‘app01:home‘ %}

路由分发如何设置首页

      如果我们想通过输入http://127.0.0.1:8000/app01/,看到app01这个应用的首页,怎么办?就像现在输入一个http://127.0.0.1:8000来查看网站的首页,怎么办?

      url(r‘^$‘, views.index),#以空开头,还要以空结尾,写在项目的urls.py文件里面就是项目的首页,写在应用文件夹里面的urls.py文件中,那就是app01的首页



以上是关于django学习第十三天的主要内容,如果未能解决你的问题,请参考以下文章

第十三天学习笔记

第十三天

我的python学习--第十三天

Linux课程第十三天学习笔记

马哥教育M28第十三天到第十五天学习总结

学习python第十三天