飞道的博客

2020年最新Django经典面试问题与答案汇总(下)-大江狗整理

434人阅读  评论(0)

终于我们来到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里已经注册了一些自带的中间件,每个中间件都负责一个特定的功能。


   
  1. MIDDLEWARE = [
  2. 'django.middleware.security.SecurityMiddleware',
  3. 'django.contrib.sessions.middleware.SessionMiddleware',
  4. 'django.middleware.common.CommonMiddleware',
  5. 'django.middleware.csrf.CsrfViewMiddleware',
  6. 'django.contrib.auth.middleware.AuthenticationMiddleware',
  7. 'django.contrib.messages.middleware.MessageMiddleware',
  8. 'django.middleware.clickjacking.XFrameOptionsMiddleware',
  9. ]
每个中间件的功能如下,建议都保留:
  • 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_limitsoft_time_limit属性来给每个任务设置超时时间。两者区别是:

  • time_limit参数超时直接kill掉当前worker;

  • soft_time_limit参数超时时会报错而不会kill当前worker,可以捕获。


   
  1. @app.task(name= 'tasks.main', bind=True, soft_time_limit= 2, errback=error_fun)
  2. def task_main(self, param):
  3. try:
  4. time.sleep( 10)
  5. except SoftTimeLimitExceeded as e:
  6. print e

更多阅读:

Django中使用Celery执行异步和定时任务的注意事项

如何使用Django+Celery执行异步任务和定时任务

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文件。


   
  1. from django.shortcuts import render
  2. from django.template.loader import render_to_string
  3. import os
  4. def my_view(request):
  5. context = { 'some_key': 'some_value'}
  6. static_html = '/path/to/static.html'
  7. if not os.path.exists(static_html):
  8. content = render_to_string( 'template.html', context)
  9. with open(static_html, 'w') as static_file:
  10. static_file.write(content)
  11. 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第三方库

答案不限于:

更多阅读:

你应该使用的10个流行的Django第三方包

你应该使用的10个流行的Django第三方包

希望本文对大家有所帮助,喜欢的点赞啊。接下来小编我准备分享些实战项目,请关注我们的微信公众号【Python Web与Django开发】并加星标哦。

大江狗

2020.4.24


转载:https://blog.csdn.net/weixin_42134789/article/details/105743158
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场