终于我们来到Django经典面试问题与答案系列的终章了,在本章我们将分享最后10个常用有用的知识点,也是面试时常问的经典问题。如果你还没有读过本系列前两篇文章的,可以点击如下链接阅读。
21. 说说看Django信号(Signals)的工作原理, 主要应用场景及内置信号
Django 提供一个了“信号分发器”机制,允许解耦的应用在框架的其它地方发生操作时会被通知到。 通俗而讲Django信号的工作原理就是当某个事件发生的时候会发出一个信号(signals), 而监听这个信号的函数(receivers)就会立即执行。Django信号的应用场景很多,尤其是用于不同模型或程序间的联动。常见例子包括创建User对象实例时创建一对一关系的UserProfile对象实例,或者每当用户下订单时触发给管理员发邮件的动作。
Django内置信号包括:
django.db.models.signals.pre_save & post_save在模型调用 save()方法之前或之后发送。
django.db.models.signals.pre_init& post_init在模型调用_init_方法之前或之后发送。
django.db.models.signals.pre_delete & post_delete在模型调用delete()方法或查询集调用delete() 方法之前或之后发送。
django.db.models.signals.m2m_changed在模型多对多关系改变后发送。
django.core.signals.request_started & request_finished Django建立或关闭HTTP 请求时发送。
更多阅读:
Django基础(31): 如何理解和正确使用Django信号(Signals)
22. 什么是中间件(middleware),中间件(middleware)的应用场景
中间件(Middleware)是一个镶嵌到django的request/response处理机制中的一个钩子(hooks) 框架。它是一个可以修改django全局输入或输出的一个底层插件系统。
一个请求HttpRequest在传递给视图View处理前要经过中间件处理,经过View处理后的响应也要经过中间件处理才能返回给用户。我们可以编写自己的中间件实现权限校验,限制用户请求、打印日志、改变输出内容等多种应用场景,比如:
禁止特定IP地址的用户或未登录的用户访问我们的View视图函数
对同一IP地址单位时间内发送的请求数量做出限制
在View视图函数执行前记录用户的IP地址
在View视图函数执行前传递额外的变量或参数
在View视图函数执行前或执行后把特定信息打印到log日志
在View视图函数执行后对reponse数据进行修改后返回给用户
更多阅读
Django基础(33): 中间件(middleware)的工作原理和应用场景举例
23. Django有哪些内置中间件及每个中间件的作用
Django的settings.py里已经注册了一些自带的中间件,每个中间件都负责一个特定的功能。
-
MIDDLEWARE = [
-
'django.middleware.security.SecurityMiddleware',
-
'django.contrib.sessions.middleware.SessionMiddleware',
-
'django.middleware.common.CommonMiddleware',
-
'django.middleware.csrf.CsrfViewMiddleware',
-
'django.contrib.auth.middleware.AuthenticationMiddleware',
-
'django.contrib.messages.middleware.MessageMiddleware',
-
'django.middleware.clickjacking.XFrameOptionsMiddleware',
-
]
每个中间件的功能如下,建议都保留:
SecurityMiddleware:为request/response提供了几种安全改进,无它不安全
SessionMiddleware:开启session会话支持,无它无session
CommonMiddleware:基于APPEND_SLASH和PREPEND_WWW的设置来重写URL,如果APPEND_SLASH设为True,并且初始URL 没有以斜线结尾以及在URLconf 中没找到对应定义,这时形成一个斜线结尾的新URL;如果PREPEND_WWW设为True,前面缺少 www.的url将会被重定向到相同但是以一个www.开头的url。
CsrfViewMiddleware:添加跨站点请求伪造的保护,通过向POST表单添加一个隐藏的表单字段,并检查请求中是否有正确的值,无它无csrf保护
AuthenticationMiddleware:在视图函数执行前向每个接收到的user对象添加HttpRequest属性,表示当前登录的用户,无它用不了request.user
MessageMiddleware:开启基于Cookie和会话的消息支持,无它无message
XFrameOptionsMiddleware:对点击劫持的保护
24. Django项目中什么时候使用中间件,什么时候使用装饰器?
中间件和装饰器均广泛用于权限校验,缓存和日志。中间件对Django的输入或输出的改变是全局的,而装饰器一般只改变单个视图的输入输出。如果让你希望对Django的输入或输出做出全局性的改变时,需要使用中间件,否则使用装饰器。
举个例子,我们在装饰器一文中介绍了如何使用@login_required装饰器要求用户必须先登录才能访问我们的某个视图函数。试想我们有个网站绝大部分视图函数都需要用户登录,每个视图函数前面都需要加上@login_required装饰器是比较傻的行为。借助于中间件,我们无需使用装饰器即可全局实现:只有登录用户才能访问视图函数,匿名用户跳转到登录页面。实现原理也很简单,在一个request到达视图函数前,我们先对request.user是否验证通过进行判断,然后再进行跳转。
更多阅读:
Django基础(26): 常用装饰器应用场景及正确使用方法
一文看懂Python系列之装饰器(decorator)(工作面试必读)
25. 使用Celery执行异步任务时如何给任务设置超时时间?
如果希望全局性地设置每个任务的超时时间,可以使用如下设置:
CELERYD_TASK_TIME_LIMIT = 10*60 #10分钟
但如果你的项目中有多个任务,但每个任务执行的周期和执行的耗时都不一样,可以使用@task装饰器的time_limit或soft_time_limit属性来给每个任务设置超时时间。两者区别是:
time_limit参数超时直接kill掉当前worker;
soft_time_limit参数超时时会报错而不会kill当前worker,可以捕获。
-
@app.task(name=
'tasks.main', bind=True, soft_time_limit=
2, errback=error_fun)
-
def task_main(self, param):
-
try:
-
time.sleep(
10)
-
except SoftTimeLimitExceeded as e:
-
print e
更多阅读:
26. 什么情况下需要自定义context_processors(上下文处理器)
当你需要一个视图函数或模板提供或设置全局变量时,你需要使用context_processors(上下文处理器)。我们在视图和模板中可以随意使用request这个对象作为变量,不需要额外传递,就是因为django.core.context_processors.request把request变成了一个全局变量。
context_processors(上下文处理器)在很多场景下非常有用,举个实际点的例子。一个博客的每篇文章详情上都会有标签云,文章归档,友情链接等信息,这些信息每篇文章都是可以公用的信息。如果每一篇文章的DetailView都从数据库查询相关数据再返回给前端模板,这就造成了数据库查询的浪费,增加了服务器的负担。如果把这些数据通过context_processors设置成全局变量,那么所有的视图和模板都能够直接访问不需要再重复查询数据库了,是不是很帅?
我们稍后会讲解如何自定义context_processors(上下文处理器),设置视图和模板的全局变量,欢迎关注我们的微信公众号【Python Web和Django开发】
27. Django如何生成静态html文件
使用render_to_string方法生成content,然后写入html文件。
-
from django.shortcuts
import render
-
from django.template.loader
import render_to_string
-
import os
-
-
-
def my_view(request):
-
context = {
'some_key':
'some_value'}
-
-
static_html =
'/path/to/static.html'
-
-
if not os.path.exists(static_html):
-
content = render_to_string(
'template.html', context)
-
with open(static_html,
'w') as static_file:
-
static_file.write(content)
-
-
return render(request, static_html)
28. Django项目如何实现高并发?
可以从如下几个角度讲:
使用nginx进行反向代理和负载均衡
数据库分库和读写分离(含主从复制)
使用nosql数据库比如redis缓存热点数据
耗时任务(比如发邮件或写入操作)交由celery异步处理
使用Gzip或django-compressor压缩静态文件
使用CDN加速静态文件访问
29. 什么是wsgi,uwsgi,uWSGI?
WSGI (Web Server Gateway Interface)
Web服务器网关接口,是一套协议。用于接收用户请求并将请求进行初次封装,然后将请求交给web框架。实现wsgi协议的模块有:
1.wsgiref,本质上就是编写一个socket服务端,用于接收用户请求(django)
2.werkzeug,本质上就是编写一个socket服务端,用于接收用户请求(flask)
uwsgi:
与WSGI一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
uWSGI:
是一个web服务器,实现了WSGI协议,uWSGI协议,http协议,
30. 列举5个常用的Django第三方库
答案不限于:
富文本编辑器:ckeditor
调试debug工具: django-debug-toolbar
快速生成可以用于生产环境的项目目录:cookiecutter
API工具:django rest framework
更多阅读:
希望本文对大家有所帮助,喜欢的点赞啊。接下来小编我准备分享些实战项目,请关注我们的微信公众号【Python Web与Django开发】并加星标哦。
大江狗
2020.4.24
转载:https://blog.csdn.net/weixin_42134789/article/details/105743158