1. 认识Django
- Django是走大而全的方向,它最出名的是其全自动化的站点管理:使用ORM,只需要做简单的对象定义,它就能自动生成数据库结构以及全功能的管理后台。
- Django内置的ORM和框架内的其他模块耦合程度高,应用必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利;
- Django的卖点是超高的开发效率,但其性能扩展有限;采用Django的项目,在流量达到一定规模后,都需要对其进行重构,才能满足性能的要求。
- Django适用的是中小型的网站,或者是作为大型网站快速实现产品雏形的工具。
- Django模板的设计哲学是彻底的将代码、样式分离; Django从根本上杜绝在模板中进行编码、处理数据的可能。
2. Django 、Flask、Tornado
Django
走的是大而全的方向,开发效率高。它的MTV框架、自带的ORM、admin后台管理、自带的sqlite数据库和开发测试用的服务器给开发者提高了超高的开发效率Flask
是轻量级的框架:自由、灵活、可扩展性很强,核心基于Werkzeug WSGI工具和jinja2模板引擎- ·Tornado·走的是少而精的方向,性能优越。它最出名的是
异步非阻塞的设计方式
,Tornado的两大核心模块:- iostraem:对非阻塞式的socket进行简单的封装
- ioloop:对I/O多路复用的封装,它实现了一个单例
3. wsgi、uwsgi、uWSGI
WSGI
- web服务器网关接口,是一套协议。用于接收用户请求并将请求进行初次封装,然后将请求交给web框架
- 实现wsgi协议的模块:
- wsgiref(django):本质上就是编写一个socket服务端,用于接收用户请求
- werkzeug(flask):本质上就是编写一个socket服务端,用于接收用户请求
uwsgi
- 与WSGI一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
uWSGI
- 是一个web服务器,实现了WSGI协议、uWSGI协议、http协议。
4. Django请求的生命周期
WSGI
:请求封装后交给web框架 (Flask、Django)中间件
:对请求进行校验或在请求对象中添加其他相关数据,例如:csrf、request.session路由匹配
:根据浏览器发送的不同url去匹配不同的视图函数视图函数
:在视图函数中进行业务逻辑的处理,可能涉及到:orm、templates渲染中间件
:对响应的数据进行处理WSGI
:将响应的内容发送给浏览器。
5. FBV和CBV
FBV和CBV本质是一样的
- 基于函数的视图叫做FBV,基于类的视图叫做CBV
- 在python中使用CBV的优点:
- 提高了代码的复用性,可以使用面向对象的技术,比如Mixin(多继承)
- 可以用不同的函数针对不同的HTTP方法处理,而不是通过很多if判断,提高代码可读性
6. 给CBV的程序添加装饰器
# 引入method_decorator模块
# 直接在类上加装饰器
@method_decorator(test, name='dispatch')
class Loginview(View):
pass
# 直接在处理的函数前加装饰器
@method_decorator(test)
def post(self, request, *args, **kwargs):
pass
7. MVC、MVT
- MVC软件系统分为三个基本部分:
- Model(模型):负责业务对象与数据库的映射(ORM)
- View(视图):负责与用户的交互
- Controller(控制器):接受用户的输入、调用模型和视图、完成用户的请求
- Django框架的MTV设计模式借鉴了MVC框架的思想,三部分为:
- Model(模型):负责业务对象与数据库的对象(ORM)
- View(视图):负责业务逻辑,并在适当的时候调用Model和Template
- Template(模版):负责如何把页面展示给用户
- 此外,Django还有一个
urls分发器
:- 它将一个个URL的页面请求分发给不同的view处理
- view再调用相应的 Model 和 Template
8. django路由系统中name的作用
- 用于反向解析路由,相当于给url取个别名
- 只要这个名字不变,即使对应的url改变,通过该名字也能找到该条url
9. Django内置组件
Admin组件
:对model中对应的数据表进行增删改查提供的组件Model组件
:负责操作数据库Form组件
:- 生成HTML代码
- 数据有效性校验
- 校验信息返回并展示
ModelForm组件
:既可用于数据库操作,也可用于用户请求的验证
10. Django中MIDDLEWARES中间件的作用和应用场景
介于
request与response处理之间
的一道处理过程`,用于在全局范围内改变Django的输入和输出
- 简单的来说中间件是帮助我们在
视图函数执行之前和执行之后都可以做一些额外的操作
,例如:- Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确
token
值 - 当用户在页面上发送请求时,通过自定义的认证中间件,
判断用户是否已经登陆
,未登陆就去登陆。 - 当有用户请求过来时,
判断用户是否在白名单
或者在黑名单里
- Django项目中默认启用了csrf保护,每次请求时通过CSRF中间件检查请求中是否有正确
11. Django中间件的方法
process_request
:请求进来时:权限认证process_view
:路由匹配之后:能够得到视图函数process_exception
:异常时执行process_template_responseprocess
:模板渲染时执行process_response
:请求有响应时执行
12. Django中request对象创建
# 请求走到WSGIHandler类的时候,执行__cell__方法,将environ封装成了request
class WSGIHandler(base.BaseHandler):
request = self.request_class(environ)
13. Django实现重定向及状态码设置
重定向
:- 使用HttpResponseRedirect:from django.http import HttpResponseRedirect
- 使用redirect和reverse
状态码
:301和302,区别如下:- 相同点:都表示重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址
- 不同点:
- 301比较常用的场景是使用域名跳转。如访问 http://www.baidu.com 会跳转到 https://www.baidu.com,表示旧地址A的资源已经被永久地移除了
- 302用来做临时跳转,比如未登陆的用户访问用户中心重定向到登录页面。表示旧地址A的资源还在(仍然可以访问),这个重定向只是临时地从旧地址A跳转到地址B
14.xxss攻击
- XSS攻击是向网页中注入恶意脚本,用在用户浏览网页时,在用户浏览器中执行恶意脚本的攻击。
- XSS分类:
- 反射型xss:又称为非持久型xss,攻击者通过电子邮件等方式将包含注入脚本的链接发送给受害者,受害者通过点击链接,执行注入脚本,达到攻击目的。
- 持久型xss:跟反射型的最大不同是攻击脚本将被永久的存放在目标服务器的数据库和文件中,多见于论坛,攻击脚本连同正常信息一同注入到帖子内容当中,当浏览这个被注入恶意脚本的帖子的时候,恶意脚本会被执行
- XSS分类:
- 防范措施:
- 输入过滤:用户输入进行检测,不允许带有js代码
- 输出编码:就是把我们的脚本代码变成字符串形式输出出来
- cookie加密
- XSS攻击能做些什么:
- 窃取cookies
- 读取用户未公开的资料,如果:邮件列表或者内容、系统的客户资料,联系人列表
- 解决方法:
- 客户度端:表单提交之前或者url传递之前,对需要的参数进行过滤
- 服务器端:检查用户输入的内容是否有非法内容
15. Django中的CSRF实现机制
- django第一次响应来自某个客户端的请求时,后端
随机产生一个token
值 - 把这个token
保存在SESSION状态
中;同时,后端把这个token放到cookie中交给前端页面
; - 下次前端需要发起请求(比如发帖)的时候把这个token值加入到请求数据或者头信息`中,一起传给后端;Cookies:{csrftoken:xxxxx}
- 后端校验前端请求带过来的token和SESSION里的token是否一致;
16. 基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token
#1.后端将csrftoken传到前端,发送post请求时携带这个值发送
data: {
csrfmiddlewaretoken: '{{ csrf_token }}'
},
#2.获取form中隐藏标签的csrftoken值,加入到请求数据中传给后端
data: {
csrfmiddlewaretoken:$('[name="csrfmiddlewaretoken"]').val()
},
#3.cookie中存在csrftoken,将csrftoken值放到请求头中
headers:{ "X-CSRFtoken":$.cookie("csrftoken")},
17. 为什么不用runserver进行部署(uWSGI和runserver的区别)
- runserver
- 调试 Django 时经常用到的运行方式
- 它使用Django自带的 WSGI Server 运行,主要在测试和开发中使用
- 并且 runserver 开启的方式也是单进程
- uWSGI
- 是一个Web服务器,它实现了WSGI协议、uwsgi、http 等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的 Web 服务器
- 具有超快的性能、低内存占用和多app管理等优点,并且搭配着Nginx就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署
- 相比来讲,支持的
并发量更高,方便管理多进程,发挥多核的优势,提升性能
18. Cookie、Session
- cookie:
- ·保存在浏览器端的键值对·,可以用来做用户认证
- session:
- 将用户的会话信息保存在服务端
- key:是随机产生的自符串
- value:时session的内容
- ·依赖于cookie将每个用户的随机字符串保存到用户浏览器上·
- 将用户的会话信息保存在服务端
Django:session默认保存在数据库中:django_session表
flask:session默认将加密的数据写在用户的cookie中
19. Django ORM 中所有的方法(QuerySet对象的所有方法)
方法 | 释义 |
---|---|
all() | # 查询所有结果 |
filter(**kwargs) | 它包含了与所给筛选条件相匹配的对象。获取不到返回None |
get(**kwargs) | 返回与所给筛选条件相匹配的对象(有且只有一个);如果超过一个或者没有都会抛出错误 |
exclude(**kwargs) | 它包含了与所给筛选条件不匹配的对象 |
order_by(*field) | 对查询结果排序 |
reverse() | 对查询结果反向排序 |
count() | 返回数据库中匹配查询(QuerySet)的对象数量 |
first() | 返回第一条记录 |
last() | 返回最后一条记录 |
exists() | 如果QuerySet包含数据,就返回True,否则返回False |
values(*field) | 返回一个ValueQuerySet(一个特殊的QuerySet),运行后得到一个可迭代的字典序列 |
values_list(*field) | 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列 |
distinct() | 从返回结果中剔除重复纪录 |
20. only和defer的区别
only
:从数据库中只取指定字段的内容defer
:指定字段的内容不被检索
21. select_related、prefetch_related
- 有外键存在时,可以很好的减少数据库请求的次数,提高性能
select_related
:通过多表join关联查询,一次性获得所有数据,只执行一次SQL查询
prefetch_related
:分别查询每个表,然后根据它们之间的关系进行处理,执行两次查询
22. filter、exclude
取到的值都是QuerySet对象
filter
:选择满足条件的exclude
:排除满足条件的
23. F、Q
F
:对数据本身的不同字段进行操作 如:比较和更新Q
:用于构造复杂的查询条件 如:& |操作
24. values、values_list
- values:取字典的queryset
- values_list:取元组的queryset
25. django orm批量创建数据
bulk_create()
objs = [models.Book(title = "图书{}".format(i + 15)) for i in range(100)]
models.Book.objects.bulk_create(objs)
26. django的Form组件中,如果字段中包含choices参数,使用两种方式实现数据源实时更新
# 1.重写构造函数
def def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields["city"].widget.choices = models.City.objects.all().values_list("id", "name")
# 2.利用ModelChoiceField字段,参数为queryset对象
28. django的Model中的ForeignKey字段中的on_delete参数
- 删除关联表中的数据时,当前表与其关联的field的操作
- django2.0之后,表与表之间关联的时候,必须要写on_delete参数,否则会报异常
29. django如何实现websocket
30. django orm中三种能写sql语句的方法
- 使用execute执行自定义的SQL
- 使用extra方法
- 使用raw方法
- 执行原始sql并返回模型
- 依赖model多用于查询
31. Django ORM中设置读写分离
- 手动读写分离:通过.using(db_name)来指定要使用的数据库
- 自动读写分离:
- 定义类:如Router
- 配置Router
- settings.py中指定DATABASE_ROUTERS
- DATABASE_ROUTERS = [‘myrouter.Router’,]
- 提高读的性能:多配置几个数据库,并在读取时,随机选取。写的时候写到主库
- 实现app之间的数据库分离:分库分表
32. django中如何实现orm表中添加数据时创建一条日志记录
33. django内置的缓存机制
# 全站缓存
MIDDLEWARE_CLASSES = (
‘django.middleware.cache.UpdateCacheMiddleware', #第一
'django.middleware.common.CommonMiddleware',
‘django.middleware.cache.FetchFromCacheMiddleware', #最后
)
# 视图缓存
from django.views.decorators.cache import cache_page
import time
@cache_page(15) # 超时时间为15秒
def index(request):
t=time.time() # 获取当前时间
return render(request,"index.html",locals())
# 模板缓存
{% load cache %}
<h3 style="color: green">不缓存:-----{{ t }}</h3>
{% cache 2 'name' %} # 存的key
<h3>缓存:-----:{{ t }}</h3>
{% endcache %}
34. django的缓存能使用redis吗?如果可以的话,如何配置?
# 1.安装 pip install django-redis
# 2.在stting中配置CACHES,可以设置多个缓存,根据名字使用
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
# "PASSWORD": "密码",
}
}
},
#另添加缓存
"JERD": { }
# 3.根据名字去连接池中获取连接
from django_redis import get_redis_connection
conn = get_redis_connection("default")
35. django的模板中filter和simple_tag的区别
- 自定义filter:{{ 参数1|filter函数名:参数2 }}
- 可以与if标签来连用
- 自定义时需要写两个形参
- simple_tag:{% simple_tag函数名 参数1 参数2 %}
- 可以传多个参数,没有限制
- 不能与if标签来连用
36. django-debug-toolbar的作用
- 是django的第三方工具包,给django扩展了调试功能:包括查看sql语句、db查询次数、request、headers等
37. django中如何实现单元测试
38. orm中 db first 和 code first的含义
- 数据持久化的方式:
db first
基于已存在的数据库,生成模型code first
基于已存在的模型,生成数据库库
评论区