Django分了很多层
路由曾
视图层 请求对象和响应对象
模板曾
模型层:orm:表单,多表,各种查询
ajax forms组件 分页器 cookie session 中间件 auth
——————————————————————————————————————————————————————————————————————————————————————————————————————————————————————视图层响应对象
响应本质都是HttpReponse
HttpReponse---字符串
render-------放个模板 模板渲染是在后端完成的
js代码实在客户端浏览器里执行的
模板语法是在后端执行的
redirect---------重定向
-字符串参数部分是空的
状态码是 3开头 status=201
JsonResponse json格式数据
return JsonResponse({name:lqz,age:19})
本质是把传入的字典或列表(必须指定safe =False),使用 json序列化得到 json格式字符串----最终做成 HttpResponse返回给前端----- 如果想给 json序列化的时候,传参数,必须使用 json_dumps_params字典传入
如果想往响应头中写数据---需要传headers = {‘xx’:‘xx’}
JsonResponse源码分析
return JsonResponse({name:lqz,age:19}) 注:如果是列表 那么safe要改成 False 否则会抛异常
触发 JSonResponse的__init__ ----------{name:lqz,age:19} 给了data
def __init__(self, data, encoder=DjangoJSONEncoder,
safe=True,json_dumps_params=None, **kwargs):
如果传入的四字典
safe是True,后面是False,条件不符合,内部就不会走
if safe and not isinstance(data, dict):
raise TypeError(
'In order to allow non-dict objects to be serialized set the '
'safe parameter to False.'
)
if json_dumps_params is None: # 条件符合
json_dumps_params = {}
kwargs是字典---》setdefault--》有则修改,无则新增
kwargs.setdefault('content_type', 'application/json')
核心---》把字典转成json格式字符串,赋值给data
data = json.dumps(data, cls=encoder, **json_dumps_params)
super().__init__ 调用父类的 __init__ 完成实例化---》HttpResponse的对象
return HttpResponse(data,**kwargs)
super().__init__(content=data, **kwargs)
isinstance
isinstance(对象,类)判断这个对象,是不是这个类的对象
CBV和FBV
FBV:基于函数的视图
之前的都是FBV
CBV写法
from django.views import View
class UserView(View):
写方法---跟请求方式同名的方法
def get(self,request,*args,**kwargs)
必须返回四件套
路由配置:
path('index/', 视图类名.as_view()) as_view是类的绑定方法
执行流程--》源码分析
path('index/', index),--->请求来了,路由匹配成功会执行 index(request,)
path('index/', UserView.as_view()),
1 入口:路由---》as_view来开始
-请求来了,路由匹配成功---》执行---》UserView.as_view()(request)
-需要看as_view()执行结果是什么--》view--》代码如下
def view(request, *args, **kwargs): # 方法,可以加括号调用
return self.dispatch(request, *args, **kwargs)
-本质就是在执行 view(request)
-本质在执行---》self.dispatch(request, *args, **kwargs)
-去类(UserViwe类中找,找不到,去父类View)中找dispatch,代码如下
def dispatch(self, request, *args, **kwargs):
request当次请求的请求对象,取出请求方式【假设是get请求】,转成小写 'get'
http_method_names = ['get', 'post', 'put']
条件成立,执行if内部代码
if request.method.lower() in self.http_method_names:
getattr:反射---》通过字符串去对象中取属性或方法
self是谁的对象? 是View这个类的对象,这个是视图类UserView的对象
取出来的handler 是 UserView这个类的get方法
handler = getattr(self, 'get')
else:
handler = self.http_method_not_allowed
handler是 UserView这个类的get方法
get(request)---》触发UserView这个类的get方法---》真正执行原来视图函数的内容
最终返回
return handler(request, *args, **kwargs)
总结:写cbv,只需要在视图类中写跟请求方式同名的方法即可--》不同请求方式,就会执行不同的方法
关于类中self是谁的问题
class Animal:
def run(self):
这个self,是谁调用,就是谁
print(type(self))
print(self.name, '走路')
class Person(Animal):
def __init__(self, name):
self.name = name
class Dog(Animal):
def __init__(self, name,age):
self.name = name
self.age=age
p = Person('lqz')
p.run() #
dog=Dog('小奶狗',6)
dog.run()
self 是谁调用。self就是谁,不能只看是哪个类
上传文件
关于模板查找路径是配置文件中
TEMPLATES --->'DIRS': [os.path.join(BASE_DIR, 'templates')]
## python
class FileView(View):
def get(self,request):
return render(request,'file.html')
def post(self,request):
拿出文件对象
my_file=request.FILES.get('myfile')
print(type(my_file))
my_file=request.FILS.egt('myfile')
通过 print(type('my_file'))查看类型
#django.core.files.uploadedfile.InMemoryUploadedFile 跟之前用的文件对象不一样但是,它应该继承了文件
from django.core.files.uploadedfile import InMemoryUploadedFile
1 保存 2 取出文件名字
my_file.save() #找了一顿,没有,所以不能使用(save)快捷保存方式,需要自己写保存
print(my_file.name) 看neme属性是不是 这个文件的名字
3-xxxxx.md
自己写保存,放在项目根路径下
with open(my_file.name,'wb') as f:
for line in my_file:
f.write(line)
return HttpResponse('上传成功')
html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="" (默认当前地址)method="post" enctype="multipart/form-data"> --编码格式
<input type="file" name="myfile">
<br>
<input type="submit" value="提交"> 目前记得注掉 srf
</form>
</body>
</html>
此时点post提交 会报错
需要写 def post(self,request):
拿出文件
my_file=request.FILS.egt('myfile')
通过 print(type('my_file'))查看类型
模板 templease.html
模板在浏览器中运行不了,因为它有模板语法 浏览器解析不了模板语法
必须在后端渲染完成(替换完成) 变成纯粹的html,css,js
这种在后端会被渲染 类python语法 它叫模板语法 django中它又叫 dtl: django template language
django模板修改的视图函数
了解####
# ================================django模板修改的视图函数
from django.template import Template,Context
now=datetime.datetime.now()
# 内部打开了这个模板---》读出所有内容,实例化得到了t对象
t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')
# #t=get_template('current_datetime.html')
c=Context({'current_date':str(now)})
html=t.render(c)
return HttpResponse(html)
另一种写法(推荐)
import datetime
now=datetime.datetime.now()
return render(req, 'current_datetime.html', {'current_date':str(now)[:19]})
# 总结:咱们之前这么写
render(request,'模板名字',context={key:value,key1:value})
本质是:
t=Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')
c=Context({'current_date':str(now)})
html=t.render(c) # 返回是字符串
HttpResponse(html)
页面静态化#######
-把什么页面,做成静态化的?---》访问量高的页面
-目的:提高项目并发量,响应速度和效率就高了
-把首页静态化
def index(request):
# 1 判断 cache文件夹下有没有 index.html 纯静态页面
# 2 如果没有:干下面的事
# books = Book.object.all()
# t = Template('<html><body>现在时刻是:<h1>{{current_date}}</h1></body></html>')
# # #t=get_template('current_datetime.html')
# c = Context({'books':books})
# html = t.render(c)
#保存到某个文件中 cache文件夹下 index.html
# 3 如果有那个文件,打开文件---》HttpReponse
books=Book.object.all()
return render(request,'index.html',{books:books})
模板语法###
变量:{{ 变量名 }} 字典,列表,对象 通过.拿到属性或方法
字典:dic.name--->这不是python语法 dic['name'] dic.get('name')
列表:list.2--->这不是python语法 list[0]
对象:person.name---->是python语法
person.run---->不是python语法,会自动加括号,把run的返回值放在模板中 person.run()
不支持传参数
1 深度查询 用句点符
2 过滤器
3 标签:{{% % }}
内置过滤器####
# render(request,'index.html',{now:当前时间对象})
{{ now | date:"Y-m-d H:i:s" }}
safe 把标签字符串 渲染成标签
'<a href=""></a>'--->渲染成标签
dtl是不存在xss攻击的?跨站脚本攻击
# 后端:
s='
<script>
alert(1)
</script>
'
render(request,'index.html',{s:s})
#模板
{{s}} 不会渲染成标签,没有xss攻击
我们知道s是安全的,我们可以使用safe标签,把它渲染成 真正的标签
模板导入 include ,写好一段前端代码块,以后别的页面要用,直接 {% include 'little.html' %}
#### little.html 这个是以后要导入的代码块
<div>
<h1>我是广告</h1>
<p>亚洲最大同性交友平台</p>
<p>名字是:{{ name }}---诚信交友</p>
</div>
#### 在index.html 或者 login.html中想用
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<div>
{% include 'little.html' %} # 这个位置引入即可,但是如果little中有模板语法,需要如下
</div>
<hr>
<div>
我是div222
</div>
</body>
</html>
### python代码:
def index(request):
return render(request, 'index.html', {'name': '彭于晏'})
-1 {{变量}} {{变量.取值}}
-2 {%for%}
-3 {%if%}
-5 内置过滤器 :data,length。。。
-6 include
-7 extends使用
————————————————————————————————————————————————————————————————————————————————————————————————
0 cbv执行流程,self问题(写代码试试) ---》整理到笔记中
cbv执行流程: 请求进入——进行路由匹配——如果匹配到对应的路由,内部就会执行XXXview.as_view()(request),因为XXXview中没有as_view()这个方法,所以去它的父类View中找,内部开始执行,View的as_view内部的view闭包函数,闭包函数执行了self.dispatch,这里的self是在XXXview类实例化的对象,在self.dispatch中通过反射找到同名的方法,然后执行,把request传入。
# 1 你自己写一个类,实现JsonResponse 功能,不需要传safe=False,无论字典或列表,都能完成序列化返回给前端
# 2 四种情况,在响应头返回数据 xx=xx
# 3 绑定给类的方法,类来调用,对象可以调用吗?如何用
类的绑定方法可以用对象来调用
class Person:
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def test(cls):
print(cls)
print('类的绑定方法')
p = Person('jiayi',20)
#对象可以调用类的绑定方法,也是把该对象的类传过去
p.test()
# 4 绑定给对象的方法,对象来调用,类可以调用吗?如何用
能来调用,只不过是方法中需要几个参数就要传递几个参数,包括self形参也需要自己传递
class Student():
school = 'SH'
def __init__(self, name, age, gender):
self.name = name
self.age = age
self.gender = gender
"""绑定给对象来调用的"""
def tell_info(self, username, password):
print("name:%s age:%s gender:%s %s %s" % (self.name,
self.age, self.gender, username, password))
"""默认情况下,在类内部写方法是绑定给对象的,就有对象来调用,
就会自动来传递参数"""
stu = Student('ly', 20, 'male')
# 谁来调用方法就是谁,对象自己
stu.tell_info('kevin', 123)
# name:ly age:20 gender:male kevin 123
# 5 写个图片上传功能,图片保存在根路径media文件夹下,上传成功直接在前端显示出上传的图片
-开启media的访问
# 6 建个表---》插入100条数据---》写个页面,for循环把100条数据显示在页面上
-只要用户访问---》就会去查
-做成静态化
# 7 (能做就做)自定义一个过滤器---》实现
数据有个表---》content字段---》别人存入了一些敏感词
它**
高级一些:关键词放到一个列表中,可以随时增加,不需要重启项目---》数据可以放在数据库中
标签:name,补充,self,request,Django,---,html,模板 From: https://www.cnblogs.com/wzh366/p/17865804.html