【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(自己写的类产生的对象,'小写的请求方法(get\post)','获取不到对应的方法就报错') # 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) # 不停的给对象设置值
整理好博客,再温习一遍,洗洗睡吧!