view.py
后端实例化标签模版
from django.template import Template,Context # 导入模块
from django.shortcuts import render,Httpsponse,redirect
在后端实现上传标签样式及内容
def text(request):
stencil = Template("<h1>{{ user }}</h1>")
content = Context({'user': '我是谁'})
msg = stencil.center(content)
return HttpResponse(msg)
# 上述操作,标签就可以生效
json格式数据传输
from django.http import JsonResponse # 导入模块
关于正常传字典
方式一: 使用json模块
# def text(request):
# dic = {'username': 'xxx', 'password': '123', 'is_boy': True}
# json_data = json.dumps(dic,ensure_ascii=False)
# return HttpResponse(json_data)
方式二: 使用django封装的json方法
# def text(request):
# dic = {'username': 'yyy', 'password': '123', 'is_boy': True}
# return JsonResponse(dic, json_dumps_params={'ensure_ascii': False})
关于传列表
方式一: 使用json模块
# def text(request):
# lis = [1, 2, 3, 4, 5]
# json_data = json.dumps(lis, ensure_ascii=False)
# return HttpResponse(json_data)
方式二: 使用django封装的json方法
def text(request):
lis = [1, 2, 3, 4, 5]
# return JsonResponse(lis, json_dumps_params={'ensure_ascii': False}) # 报错
return JsonResponse(lis, safe=False, json_dumps_params={'ensure_ascii': False}) # 设置safe=False 不报错
# JsonResponse默认只支持字典类型,如果想要序列化其他数据类型,这个必须是json支持的数据类型,就必须设置safe=False
重写json的default,支持更多格式
我们打开源码可以知道,在源码里面 cls=None
然后往下翻我们可以看到 cls=None 所触发的条件
这个时候我们就可以看到 JSONEncoder,ctrl+鼠标右键左键,我们可以看到一个表,在里面的是json支持的数据格式
然后往下翻,我们可以看到在JSONEncoder里面有 default 方法,也就是可以控制报错的方法.
这个时候我们只要继承我们的JSONEncoder,把这个类下面的default方法重写,就可以在输入json不支持的数据的时候阻止报错了.变相的来说,就是把不支持的数据变成支持的数据了.
import json
import datetime
ctime = datetime.datetime.today()
class Myjsonclass(json.JSONEncoder):
def default(self, o):
if isinstance(o, datetime.datetime):
return o.strftime('%Y-%m-%d')
else:
super().default(self, o)
print(json.dumps({'ctime': ctime}, cls=MyJson))
# 其实就是还是不支持这种数据格式,只是在内部把他改成了字符串等json支持的格式.
还有就是这个方法是json里面自己提供的(最下面的英文)
form表单上传文件
前端:
<form action="" method="post" enctype="multipart/form-data">
<form>
<input type="text" name="username">
<input type="password" name="password">
<input type="file" name="up_file">
<button type="submit" class="btn btn-default">Submit</button>
</form>
</form>
# 前端的form表单中,只有设置 enctype="multipart/form-data",才可以上传文件
后端:
def text(request):
if request.method == 'POST':
file_obj = request.FILES.get('up_file')
# 这里拿的对象,可以对象.name,拿到上传的文件的名字
with open(file_obj.name,'wb') as fw:
for line in file_obj.chunks():
fw.write(line)
# chunks() : 这个方法是类似于 read(),但是read()是一次性读,会很占内存,这个方法是如果文件大于2.5M,就会分段传输,不会去大量使用内存,并且这个上限是可以更改的.
CBV
之前写的都是FBV,就是通过函数去写的,也就是基于函数的视图,CBV是基于类的视图.
如果在类中写了get和post两个方法,那么前端来get请求,就会触发get方法,来post请求就会出发post方法.
1. views.py
# 导包
from django.views import View
class Test(View):
def get(self, request):
return render(request, 'test1.html')
def post(self, request):
return HttpResponse('我是post请求')
2. urls.py
url(r'^test/', views.Test.as_view()),
CBV源码分析
首先,我们输入网址,就会进入路由与视图函数对应关系的地方,就会找到url(r'^test/', views.Test.as_view())
, 我们可以知道因为as_view()
是一个加括号的函数,所以就会先执行as_view()
.
ctrl+左键,点击进入源码,看到as_view()
下面的view
函数返回的就是view,这个就是一个闭包函数,也就是说as_view()
返回的其实就是view
我们再看到这个语句中的一句话.在这个里面cls其实就是views.py中我们定义的类,
self就是cls到的对象,对象点方法,应该点的是类中的属性或者方法,所以这个dispatch
应该就是类中的方法(我们写的get或者post),就想到于执行了这个方法
self因为使我们实例化对象,我们对象中是没有dispatch这个方法的,所以我们需要去类中找,类也是没有的,所以我们去父类中找,也就是找view中有没有dispatch,(这里这么找是因为我们要在看源码的时候按顺序找,而不是直接ctrl+右键点进去),然后我们就在view下面找到了dispatch方法
这个就是整个CBV的精髓。我们可以看到,首先它判断了所有获取的request.method
的小写形式在不在我源码文件中自己设置的8个请求里面,
如果在,通过反射的方式赋值给handler,然后返回返回,最终返回之前我们看到闭包的view
,也就是说如果过来的是get请求,那么as_view()就会返回get,如果过来的是post请求as_view()就会改编成post,那么urls.py的请求地址就会url(r'^test/', views.Test.get)
,url(r'^test/', views.Test.post)
,就会去执行对应的函数。如果8大请求方式里面没有的话,就会执行报错函数
Django setting源码分析
在django中我们知道有两个配置文件,一个是展示给用户的,一个是默认配置的,而setting的源码就是做了如果用户配置了,并且默认配置的文件里面有所定义的变量,那么就用用户定义的,用户写了没有的就pass,没有配置的话就用默认的。
下面是我自己写的一个简单的例子
user_setting
A = True
D = 567
# setting
A = False
B = True
C = True
D = 123
# 源码
def my_set(self):
set_lis = []
set_re_lis = []
for i in dir(setting):
if i.isupper():
set_lis.append(i)
for j in dir(setting_re):
if j.isupper():
set_re_lis.append(j)
setattr(setting, j, getattr(setting_re, j))
意思是这么个意思,简化很多的那种,就是达到用户配置了的用用户的,没有配置的用自己的