zoukankan      html  css  js  c++  java
  • day 59

    day 59

    01.importlib 模块

    1. 利用字符串导入模块
    2. 只能写到文件名为止,不能写内部的变量名
    3. 利用反射解决变量名问题

    01.基于django中间件的思想实现功能配置

    1. 以模块的方式导入

      # notify.py
      def send_email(content):
          print('邮箱通知:%s'%content)
      def send_msg(content):
          print('短信通知:%s'%content)
      def send_wechat(content):
          print('微信通知:%s'%content)
      # start.py
      from notify import *
      def send_all(content):
          send_msg(content)
          send_email(content)
          send_wechat(content)
      if __name__ == '__main__':
          send_all('再坚持一天就周末了')
      
    2. 以配置文件的形式

      # settings.py
      NOTIFY_LIST = [
          'notify.email.Email',
          'notify.msg.Msg',
          'notify.wechat.WeChat',
          'notify.qq.Qq',
      ]
      
      import settings
      import importlib
      
      def send_all(content):
          for path in settings.NOTIFY_LIST:  # 循环获取列表中的所有字符串
              module_path, cls_name = path.rsplit('.',maxsplit=1)  # 将字符串形式的文件对象和类名分开
              md = importlib.import_module(module_path)  # 获取到文件对象
              cls = getattr(md,cls_name)  # 通过反射获取到类名
              obj = cls()  # 实力化产生一个个类的对象
              obj.send(content)  # 调用按照鸭子类型写好的同类功能
      

    02.跨站请求伪造csrf

    1. 钓鱼网站原理

      1. 模仿正规网站页面,提前写好一些隐藏好的数据
    2. 解决

      1. form表单

        1. {% csrf_token %}
      2. ajax请求

        1. 方式一

          1. 在页面上书写{% csrf_token %}
          2. 在发送ajax请求时使用标签查找,携带上该数据
        2. 方式二

          1. 'csrfmiddlewaretoken':'{{ csrf_token }}'会自动显示该标签的value
        3. 方式三

          1. 直接使用官网提供的脚本文件,直接以js脚本文件的形式导入

            function getCookie(name) {
                var cookieValue = null;
                if (document.cookie && document.cookie !== '') {
                    var cookies = document.cookie.split(';');
                    for (var i = 0; i < cookies.length; i++) {
                        var cookie = jQuery.trim(cookies[i]);
                        // Does this cookie string begin with the name we want?
                        if (cookie.substring(0, name.length + 1) === (name + '=')) {
                            cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                            break;
                        }
                    }
                }
                return cookieValue;
            }
            var csrftoken = getCookie('csrftoken');
            
            function csrfSafeMethod(method) {
              // these HTTP methods do not require CSRF protection
              return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
            }
            
            $.ajaxSetup({
              beforeSend: function (xhr, settings) {
                if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
                  xhr.setRequestHeader("X-CSRFToken", csrftoken);
                }
              }
            });
            
            <!-- 直接在页面下方导入 -->
            <script src="/static/setup.js"></script>
            
    3. csrf相关装饰器

      1. csrf_exempt;不校验csrf
      2. csrf_protect;校验csrf
      3. 两个装饰器在CBV上的区别
        1. csrf_exempt只能使用装饰在dispatch上
        2. csrf_protect和正常的装饰器一样

    03.auth模块

    auth模块时django自带的用户认证模块,默认使用auth_user表啊来存储用户数据

    1. 如何创建超级用户(root)

      1. python3 manage.py createsuperuser
      2. 会自动给密码加密
    2. 操作auth_user表

      1. 创建用户

        from django.contrib.auth.models import User
        create_user()  # 创建普通用户
        create_superuser()  # 创建超级用户
        # 创建的用户密码会自动加密
        
      2. 校验用户名和密码是否正确(必须传用户名和密码两个参数)authenticate

        obj = auth.authenticate(request,username=username,password=password)
        # 会自动将密码加密后验证,成功会返回数据对象
        
      3. 保存用户登录状态 login

        from django.contrib import auth
        auth.login(request,obj)  
        # 会在后端生成相应的session数据
        # 只要执行了这句话,后面在任意位置只要能拿到request你就可以request.user获取到当前登录的用户对象
        
      4. 判断当前用户是否登录

        request.user.is_authenticated()  # 返回布尔值
        
      5. 登录装饰器

        # 登录装饰器,用来校验当前用户是否登录
        # 局部配置
        @login_reqired(login_url='/login/')
        def index(request):
          pass
        # 全局配置 settings配置文件中
        LOGIN_URL = '/login/'
        @login_reqired
        def index(request):
          pass
        
      6. 校验密码

        request.user.check_password(password)  # 单独判断密码是否正确
        
      7. 修改密码

        request.user.set_password(password)
        request.user.save()  # 修改之后一定要保存
        
      8. 退出登录

        auth.logout(request)  # 会自动将session值删掉
        
      9. auth_user扩展字段

        1. 方式一;利用外键一对一作扩展

          class UserDetail(models.Model):
            phone = models.BigIntegerField()
            user = models.OneToOneField(to='User')
          
        2. 方式二;利用面向对象的继承

          1. 继承AbstractUser

            from django.contrib.auth.models import AbstractUser
            class UserInfo(AbstractUser):
              phone = models.CharFied
            
          2. 在配置文件中修改auth模块指定表

            AUTH_USER_MODEL = 'app01.UserInfo'  # 应用名.表名
            # 所有的auth功能以这个表为准
            
          3. 只能在项目新创建时进行修改,执行数据库迁移命令之前

      04.如何将django中settings的思想应用到自己的项目中

      1. diango中有两个配置文件
      2. 一个是暴露给用户配置的
      3. 一个是内部全局的(一旦用户配置了,就是用用户的,否则使用全局的)
      4. 在加载配置时先加载全局的在加载用户的,一旦有重复的用户配置,会覆盖掉全局的
      # lib.conf.__init__.py
      import importlib
      from lib.conf import global_settings
      import os
      
      class Settings(object):
          def __init__(self):
              for name in dir(global_settings):
                  if name.isupper():
                      k = name
                      v = getattr(global_settings,name)
                      setattr(self,k,v)  # 加载全局配置
              module_path = os.environ.get('xxx')
              md = importlib.import_module(module_path)
              for name in dir(md):
                  if name.isupper():
                      k = name
                      v = getattr(md,name)
                      setattr(self,k,v)  # 加载用户配置
      
      # lib.conf.global_settings.py
      NAME = '我是项目默认的配置文件'
      # conf.settings.py
      NAME = '我是用户自定义配置文件'
      
      # start.py
      import os
      import sys
      
      BASE_DIR = os.path.dirname(__file__)
      sys.path.append(BASE_DIR)
      
      if __name__ == '__main__':
          # os.environ.setdefault('xxx','conf.settings') 
          os.environ['xxx'] = 'conf.settings'  # 效果相同
          from lib.conf import settings
          print(settings.NAME)
      
  • 相关阅读:
    通过 INotifyPropertyChanged 实现观察者模式(转)
    Asp.net MVC中的ViewData与ViewBag(转)
    FireFox地址栏百度搜索
    ZigBee设备类型
    Array.prototype.slice.call(arguments) (转)
    泛型方法扩展
    定义IE的文档兼容模式
    C# Lazy<T>(转)
    AutoCAD2010/2012去掉搜索框
    python 集合类型
  • 原文地址:https://www.cnblogs.com/luocongyu/p/11991591.html
Copyright © 2011-2022 走看看