zoukankan      html  css  js  c++  java
  • 【1023 | Day 51】Django进阶(render原理/json相关知识/form表单/FBV和CBV/settings源码分析...)

    1. render原理

    2.json相关知识

    2.1 给前端返回json格式字符串

    • 为什么要给前端返回json格式字符串?
    》》前后端分离
    》》基于json格式传输数据
    》》后端就专门写接口
    》》前端调用接口
    》》拿到json格式的字符串
    》》然后前端利用序列化反序列化
    》》转换成前端对应的数据类型
    
    • 前端如何序列化反序列化?

      #前端
      JSON.stringify >>> json.dumps
      JSON.parse >>> json.loads
      
      #后端
      json.dumps >>> JSON.stringify 
      json.loads >>> JSON.parse
      
      #js常用数据类型
      数值、字符、数组[]、自定义对象、undefined、null、布尔值 true/false(小写)、symbol
      

    2.2 形似json

    2.3 中文乱码

    解决路径:

    • 方法一:

      • 加一个ensure_ascii

    • 方法二:

      • 给源码里的json_dumps_parms默认的空字典加一个键值对

    2.4 json序列化时间类型

    注意:default就是默认不支持datetime序列化

    解决路径:json支持序列化时间类型

    • 方法一:
      • dumps里的cls默认只能做那张表的功能
      • 我们重新定义一个类
      • 重写default方法
      • 如果o不是json默认能够序列化的
      • 重写其他方法只需要将datetime改成你要的方法

    2.5 JsonResponse

    JsonResponse 默认只支持字典

    注意:如果你想序列化其他类型(json能够支持的类型),只需要加一个safe=False。

    3. form表单上传文件

    问题:

    • CRSF错误 —— 关闭MIDDLEWARE的django.middleware.csrf.CsrfViewMiddleware
    • 只能拿到文件名

    分析:

    • 这次文件名字拿不到了,因为针对文件数据不会放进request.POST里面
    • 而是放在request.FILES里面

    解决路径:

    • 在form表单里加入enctype="multipar/form-data"

    • 插入<input type="file" name="myfile">

    • 获取文件对象

      注意:要区分POST/GET

    • 获取

    • 保存

    注意!!!这里有两点需要注意!!!

    第一,我不是楚雨荨!

    第二,我不叫喂!

    fine,开个玩笑,哈哈哈

    • 第一,提交方式必须是post,因为get能携带的参数很小。
    • 第二,form标签的enctype属性由默认的urlencoded变成formdata

    敲黑板敲黑板!

    4. FBV与CBV(即CBV源码分析)

    4.1 FBV(Function Based View) 基于函数的视图

    4.2 CBV(Class Based View) 基于类的视图

    • 之前urls一一对应views功能,现在怎么写类?

      • url(r'^login/', views.MyReg.as_view())
        

      • 通过分析as_view()的源码,发现类.方法相当于之前FBV的文件名.函数,相当于一个闭包函数

    • 为什么前端传来GET就会执行GET,传来POST就会执行POST?

      • CBV路由
      
          url(r'^reg/',views.MyReg.as_view())
          
          @classonlymethod
          def as_view(cls, **initkwargs):
              def view(request, *args, **kwargs):
                  self = cls(**initkwargs)  # cls就是我们自己的写的MyReg类
                  if hasattr(self, 'get') and not hasattr(self, 'head'):
                      self.head = self.get
                  self.request = request
                  self.args = args
                  self.kwargs = kwargs
                  # 上面的一通操作 就是给我们自己写的类的对象赋值
                  return self.dispatch(request, *args, **kwargs)
                  # 对象在查找属性或方法的时候 顺序是什么?  先从自己找 再从产生对象的类中找  再去类的父类中找...
                  """也就意味着你在看源码的时候 你一定要牢记上面的话"""
              return view
          
          # views.py 
          from django.views import View
      
          class MyReg(View):
              def get(self,request):
                  return render(request,'reg.html')
      
              def post(self,request):
                  return HttpResponse("我是MyReg类中post方法")
      
      • CBV最精髓的部分
      	def dispatch(self, request, *args, **kwargs):
              if request.method.lower() in self.http_method_names:  # 判断当前请求方式在不在默认的八个请求方式中
                  handler = getattr(self, request.method.lower(), self.http_method_not_allowed)
                  # handler = getattr(自己写的类产生的对象,'小写的请求方法(getpost)','获取不到对应的方法就报错')
                  # handler就是我们自己定义的跟请求方法相对应的方法的函数内存地址
              else:
                  handler = self.http_method_not_allowed
              return handler(request, *args, **kwargs)  # 在调用获取到的方法
      

    5. django settings源码分析及实际应用

    先思考我们之前的一个知识点:当我们输入login、register等,网站会自动帮我们添上/

    我们为了解决这个问题,用到了settins.py里面的一个语法:APPEND_SLASH:False

    当我们将这条语法换成小写的:append_slash:flash

    !!!

    问题来了

    此时运行,该命令是失效的,所以系统依旧会自动帮我们加上斜杠。

    现在就需要分析settings.py的源码了。

    5.1 django的配置文件

    • 一个是暴露给用户可以自定义配置

    • 一个是默认的全局配置文件

      用户指定了就用用户的
      用户没有指定就用默认的

    from django.conf import settings
    
    settings = LazySettings()
    
    class LazySettings(LazyObject):
            
            def _setup(self, name=None):
         
                # os.environ你可以把它看成是一个全局的大字典
                settings_module = os.environ.get(ENVIRONMENT_VARIABLE)  # 从大字典中取值
                
                # settings_module = 'day59.settings'
                self._wrapped = Settings(settings_module)  # Settings('day59.settings')
        
    class Settings(object):
        def __init__(self, settings_module):  # settings_module = 'day59.settings'
            
            for setting in dir(global_settings):  # 循环获取global_settings文件中所有的名字
                
                if setting.isupper():  # 在判断名字是否是大写
                    
                    # 如果是大写 利用反射 获取到大写的名字所对应的值  不停地添加到对象中
                    setattr(self, setting, getattr(global_settings, setting))
                    
                    # store the settings module in case someone later cares
                    self.SETTINGS_MODULE = settings_module
                    mod = importlib.import_module(self.SETTINGS_MODULE)  # 'day59.settings'
                    
                    # from day59 import settings
                    # mod 指代的就是暴露给用户的配置文件模块名
               
                    for setting in dir(mod):  # 循环获取暴露给用户配置文件中所有的名字
                        if setting.isupper():  # 判断是否是大写
                            setting_value = getattr(mod, setting)  # 如果是大写 获取大写的变量名所对应的值
                            setattr(self, setting, setting_value)  # 不停的给对象设置值
    

    整理好博客,再温习一遍,洗洗睡吧!

  • 相关阅读:
    正则 不匹配某个单词
    希赛 系统架构设计师教程 勘误
    QQ 快速登录中获取用户信息
    requests 配置tor代理后提示'Failed to establish a new connection: [Errno -2] Name or service not known'
    xadmin choice filter 多选
    kali linux 热点 无法获取IP
    windows10 输入法添加小鹤双拼
    del: recycle for linux
    安装WSL2
    cmake(转载)
  • 原文地址:https://www.cnblogs.com/fxyadela/p/11727806.html
Copyright © 2011-2022 走看看