Django面试总结
本文最后更新于:2024年7月6日 早上
自己整理的一些面试题,持续更新中。。。
django、flask、tornado框架的比较?
django:
优点:最全能的web开发框架,各种功能完备,可维护性高,开发速度快
缺点:django orm 跟数据库的交互,django同步特性导致吞吐量小的问题可以通过celery解决
tornado:
优点:天生异步,性能强悍
缺点:框架提供的功能比较少,需要自己实现,这样导致了开发速度偏慢
flask:
优点:自由、灵活,扩展性强,第三方库的选择面广
缺点:但是对程序员要求更高
什么是wsgi?
https://www.jianshu.com/p/679dee0a4193
WSGI,描述web server如何与web application通信的一种规范
WSGI协议主要包括server和application两部分:
WSGI server负责从客户端接收请求,将request转发给application,将application返回的response返回给客户端;
WSGI application接收由server转发的request,处理请求,并将处理结果返回给server。
application中可以包括多个栈式的中间件(middlewares),这些中间件需要同时实现server与application,因此可以在WSGI服务器与WSGI应用之间起调节作用:对服务器来说,中间件扮演应用程序,对应用程序来说,中间件扮演服务器。
django请求的生命周期?
Django的请求生命周期是指当用户在浏览器上输入url到用户看到网页的这个时间段内,Django后台所发生的事情
而Django的生命周期内到底发生了什么呢??
- 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端
请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中. - url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配,
一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了. - 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.
- 客户端浏览器接收到返回的数据,经过渲染后显示给用户.
列举django的内置组件
- 认证组件
- 缓存
- 日志
- 邮件
- 分页
- 静态文件管理
- 资讯聚合
- 消息框架
- 数据验证
列举django中间件的5个方法?以及django中间件的应用场景?
在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法
在django项目的settings模块中,有一个 MIDDLEWARE_CLASSES 变量,其中每一个元素就是一个中间件
默认的中间件有哪些
中间件中可以定义五个方法,分别是:
1 |
|
django中间件的使用场景
如果你想修改请求,例如被传送到view中的HttpRequest对象
或者你想修改view返回的HttpResponse对象,这些都可以通过中间件来实现
可能你还想在view执行之前做一些操作,这种情况也可以用 middleware来实现。
比如我们写一个判断浏览器来源,是pc还是手机,这里手机我们采用iphone,因为暂时没有其他设备。我们有不想把这个逻辑加到视图函数里,想作为一个通用服务,作为一个可插拔的组件被使用,最好的方法就是实现为中间件或者说做一个拦截器,发现一定的时间内某个ip对网页的访问次数过多,则将其加入黑名单
简述什么是FBV和CBV?
FBV(function base views) 基于函数的视图
CBV(class base views) 基于类的视图
使用fbv的模式,在url匹配成功之后,会直接执行对应的视图函数
使用cbv模式,在url匹配成功之后,会找到视图函数中对应的类,然后这个类回到请求头中找到对应的Request Method
用户发送url请求,Django会依次遍历路由映射表中的所有记录,一旦路由映射表其中的一条匹配成功了,就执行视图函数中对应的函数名,这是fbv的执行流程
当服务端使用cbv模式的时候,用户发给服务端的请求包含url和method,这两个信息都是字符串类型
服务端通过路由映射表匹配成功后会自动去找dispatch方法,然后Django会通过dispatch反射的方式找到类中对应的方法并执行
类中的方法执行完毕之后,会把客户端想要的数据返回给dispatch方法,由dispatch方法把数据返回经客户端
django的request对象是在什么时候创建的?
当请求一个页面时,Django创建一个 HttpRequest 对象.该对象包含 request 的元数据. 然后 Django 调用相应的 view 函数(HttpRequest 对象自动传递给该view函数<作为第一个参数>), 每一个 view 负责返回一个 HttpResponse 对象.
requests的元数据包括path,get,put等方法,cookies,user等等
如何给CBV的程序添加装饰器?
CBV添加装饰器有两种方法
- 在指定方法上添加装饰器
- 在类上添加,但是要用name来指定方法
1 |
|
总结
- 添加装饰器前必须导入from django.utils.decorators import method_decorator
- 添加装饰器的格式必须为@method_decorator(),括号里面为装饰器的函数名
- 给类添加是必须声明name
- 注意csrf-token装饰器的特殊性,它只能加在dispatch上面
列举django orm 中所有的方法(QuerySet对象的所有方法)
从数据库中查询出来的结果一般是一个集合,这个集合叫做 QuerySet
- filter 过滤
- exclude 排除
- annotate 聚合
- order_by 排序
- reverse 反向排序
- distinct 去除查询结果中重复的行
- values 迭代时返回字典而不是模型实例对象
- values_list 迭代时返回元组而不是字典
- dates 表示特定种类的所有可用日期
- datetimes 表示特定种类的所有可用日期
- none 不返回任何对象
- all 返回所有结果
- select_related 外键查询
- prefetch_related 在单个批处理中自动检索每个指定查找的相关对象
- defer 告诉django不要查询某些字段
- using 多个数据库时控制QuerySet在哪个数据库上求值
only和defer的区别?
在复杂的情况下,表中可能有些字段内容非常多,取出来转化成 Python 对象会占用大量的资源。
这时候可以用 defer 来排除这些字段,比如我们在文章列表页,只需要文章的标题和作者,没有必要把文章的内容也获取出来(因为会转换成python对象,浪费内存)
和 defer 相反,only 用于取出需要的字段,假如我们只需要查出 作者的名称
select_related
和prefetch_related
的区别?
https://hk.saowen.com/a/bb124ab70580b722d7840c7c0377a326ac4ce022dc653f4cbc7e0ae7fc245232
filter和exclude的区别?
filter 设置要查询的字段
exclude 设置不要查询的字段
列举django orm中三种能写sql语句的方法
- 使用extra:查询人民邮电出版社出版并且价格大于50元的书籍
1 |
|
- 使用raw
1 |
|
- 自定义sql
1 |
|
django orm 中如何设置读写分离?
https://blog.csdn.net/Ayhan_huang/article/details/78784486
https://my.oschina.net/candiesyangyang/blog/203425
F和Q的作用?
F作用:操作数据表中的某列值,F()允许Django在未实际链接数据的情况下具有对数据库字段的值的引用,不用获取对象放在内存中再对字段进行操作,直接执行原生产sql语句操作
使用场景:对数据库中的所有的商品,在原价格的基础上涨价10元
1 |
|
Q作用:对对象进行复杂查询,并支持&(and),|(or),~(not)操作符
使用场景:filter查询条件只有一个,而使用Q可以设置多个查询条件
1 |
|
当同时使用filter的关键字查询和Q查询时,一定要把Q对象放在前面
1 |
|
values和values_list的区别
values 返回字典而不是模型查询对象
values-list 跟values一样,但是返回的是元组
https://blog.csdn.net/weixin_40475396/article/details/79529256
如何使用django orm批量创建数据?
如果使用django save()创建数据,则每次save的时候都会访问一次数据库
1 |
|
django1.4之后加入新特性可以批量创建对象,减少SQL查询次数
1 |
|
django的Form和ModeForm的作用?
http://www.cnblogs.com/caochao-/articles/8412830.html
表单的作用是收集元素中的内容
Form 需要自己定义表单的字段
ModelForm 根据model来生成表单的字段
django的Form组件中,如果字段中包含choices参数,请使用两种方式实现数据源实时更新
此问题只适用于From组件,ModelFrom组件不用考虑(自身已经解决)
示例:例如choice类型字段,添加了新的数据,而在页面中不能显示出来,只有再次刷新页面才能获取最新的数据,因为程序运行时静态字段只加载一次, choice的数据如果从数据库获取可能会造成数据无法实时更新
1 |
|
方法一:重写构造方法:
1 |
|
方法二:使用ModelChoiceField字段
1 |
|
django的Model中的ForeignKey字段中的on_delete参数有什么作用?
当一个被ForeignKey引用的对象删除后,django将会通过指定on_delete参数来仿真sql约束的行为
例如,如果你有一个可以为空的ForeignKey,在其引用的对象被删除的时你想把这个ForeignKey 设置为空:
1 |
|
on_delete
有CASCADE
、PROTECT
、SET_NULL
、SET_DEFAULT
、SET()
五个可选择的值
- CASCADE: 级联删除;默认值
- PROTECT: 抛出ProtectedError 以阻止被引用对象的删除,它是django.db.IntegrityError 的一个子类
- SET_NULL: 把ForeignKey 设置为null; null 参数为True 时才可以这样做
- SET_DEFAULT: ForeignKey 值设置成它的默认值;此时必须设置ForeignKey 的default 参数
- SET: 设置ForeignKey 为传递给SET() 的值,如果传递的是一个可调用对象,则为调用后的结果。在大部分情形下,传递一个可调用对象用于避免models.py 在导入时执行查询
django中csrf的实现机制?
https://blog.csdn.net/u011715678/article/details/48752873
django如何实现websocket?
http://www.ruanyifeng.com/blog/2017/05/websocket.html
HTTP 协议有一个缺陷:通信只能由客户端发起
WebSocket 协议它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送技术的一种
django实现websocket有多种方式:
- 使用Channels实现websocket
https://www.jianshu.com/p/3de90e457bb4
- 使用dwebsocket实现Websocket
https://www.cnblogs.com/huguodong/p/6611602.html
http://gtcsq.readthedocs.io/en/latest/others/websocket.html
基于django使用ajax发送post请求时,都可以使用哪种方法携带csrf token?
1、写在Ajax beforeSend
1 |
|
2、写到Ajax Data
1 |
|
3、写到ajaxSetup
1 |
|
4、KindEditor携带CSRF
1 |
|
django中如何实现orm表中添加数据时创建一条日志记录
- 使用信号记录
- 使用logger
https://blog.csdn.net/apple9005/article/details/73608994
django缓存如何设置?
https://www.cnblogs.com/linxiyue/p/7494540.html
django的缓存能使用redis吗?如果可以的话,如何配置?
https://www.jianshu.com/p/04ef84c3fe3b
django路由系统中name的作用?
https://www.cnblogs.com/no13bus/p/3767521.html
https://code.ziqiangxuetang.com/django/django-url-name.html
django的模板中filter和simple_tag的区别?
https://blog.csdn.net/huanhuanq1209/article/details/77756446
django-debug-toolbar的作用?
https://www.cnblogs.com/Lands-ljk/p/5506766.html
django中如何实现单元测试?
https://www.jianshu.com/p/15af33d2c2c4
解释orm中 db first 和 code first的含义
db first:现有数据库,然后从数据库反向生成models.py
code first: 现有models.py 再进行数据库操作
django中如何根据数据库表生成model中的类
https://www.jianshu.com/p/037bd7e20a7a
使用orm和原生sql的优缺点?
使用 ORM 最大的优点就是快速开发,让我们将更多的精力放在业务上而不是数据库上,下面是 ORM 的几个优点
- 隐藏了数据访问细节,使通用数据库交互变得简单易行。同时 ORM 避免了不规范、冗余、风格不统一的 SQL 语句,可以避免很多人为的 bug,方便编码风格的统一和后期维护。
- 将数据库表和对象模型关联,我们只需针对相关的对象模型进行编码,无须考虑对象模型和数据库表之间的转化,大大提高了程序的开发效率。
- 方便数据库的迁移。当需要迁移到新的数据库时,不需要修改对象模型,只需要修改数据库的配置。
ORM 的最令人诟病的地方就是性能问题,不过现在已经提高了很多,下面是 ORM 的几个缺点
- 性能问题
- 自动化进行数据库关系的映射需要消耗系统资源
- 程序员编码
- 在处理多表联查、where 条件复杂的查询时,ORM 可能会生成的效率低下的 SQL
- 通过 Lazy load 和 Cache 很大程度上改善了性能问题
- SQL 调优,SQL 语句是由 ORM 框架自动生成,虽然减少了 SQL 语句错误的发生,但是也给 SQL 调优带来了困难。
- 越是功能强大的 ORM 越消耗内存,因为一个 ORM Object 会带有很多成员变量和成员函数。
- 对象和关系之间并不是完美映射
一般来说 ORM 足以满足我们的需求,如果对性能要求特别高或者查询十分复杂,可以考虑使用原生 SQL 和 ORM 共用的方式
使用原生sql优点:
- 进行复杂的查询时更加灵活
- 可以根据需要编写特殊的sql语句
使用原生sql缺点:
- 需要对输入进行严格的检测
- 自己写的sql语句,很多时候使用的是字符串拼接,可能会有sql注入的漏洞
- 不能使用django orm相关的一些特性
简述MVC和MTV
昨天有位同学私信我,说他所在的公司的不少项目都有个controllers.py的文件或者controllers的目录用来存放视图。但是和他理解的Python Web框架的设计模式不太一样,问我MVC/MVT到底怎么区分。听他一开始说,我为之一怔,因为我身边的人就有写controllers的… 不过我没有去验证这只是目录的名字而已。
今天我和大家聊聊我对这几个流行的设计模式的理解。
复杂的软件必须有清晰合理的架构,否则无法开发和维护。 - 阮一峰
MVC
MVC(Model View Controller 模型-视图-控制器)是一种Web架构的模式(本文不讨论桌面应用的MVC),它把业务逻辑、模型数据、用户界面分离开来,让开发者将数据与表现解耦,前端工程师可以只改页面效果部分而不用接触后端代码,DBA可以重新命名数据表并且只需更改一个地方,无需从一大堆文件中进行查找和替换。MVC模式甚至还可以提高代码复用能力。现在几乎所有的Web开发框架都建立在MVC模式之上。 当然,最近几年也出现了一些诸如MVP, MVVM之类的新的设计模式。 但从技术的成熟程度和使用的广泛程度来讲,MVC仍是主流。
MVC三要素:
Model(数据模型)。是对客观事物的抽象。比如上篇我们说到的知乎Live,Live就是一个模型,可以用Live类来表示。而一个模型通常还带有很多的和业务相关的逻辑,比如添加,更新,获取Live主讲人信息等等,这些组成了模型的方法。对于开发者模型的表示方法非常易懂和清晰,可以通过非常便捷的代码来做CURD操作而无需写一条又一条的SQL语句。
View(视图)。呈现给用户的效果,呈现的内容是基于Model,它也是收集用户输入的地方。比如看到一篇Live,数据是一个Live.get(live_id).to_dict()的结果,效果是通过对应的模板和样式把这个数据展示出来。
Contorller(控制器)。是Model和View之间的沟通者。 因为View中不会对Model作任何操作,Model不会输出任何用于表现的东西,如HTML代码或者某种效果等,它就是点数据。而Contorller用于决定使用哪些Model,对Model执行什么操作,为视图准备哪些数据,是MVC中沟通的桥梁。
MVC的特点是单向的:
浏览器发送请求
Contorller和Model交互获取数据
Contorller调用View
View渲染数据返回
MTV
和Rails、Spring、Laravel等其他语言的Web框架不一样,在Python的世界中,基本(除了Pylons)都使用了MVC的变种MTV(Model Templates View 模型-模板-视图):
Model(数据模型)。和MVC的Model一样,处理与数据相关的所有事务:如何存取、如何确认有效性、包含哪些行为以及数据之间的关系等。
Template(模板)。处理与表现相关的决定:如何在页面或其他类型文档中进行显示出来。
View。处理业务逻辑,视图就是一个特定URL的回调函数,回调函数中描述数据:从Model取出对应的数据,调用相关的模板。它就是Contorller要调用的那个用来做Model和View之间的沟通函数,从而完成控制。
注意啦:MVC中的View的目的是「呈现哪一个数据」,而MTV的View的目的是「数据如何呈现」。
也就是把MVC中的View分成了视图(展现哪些数据)和模板(如何展现)2个部分,而Contorller这个要素由框架自己来实现了,我们需要做的就是把(带正则表达式的)URL对应到视图就可以了,通过这样的URL配置,系统将一个请求发送到一个合适的视图。
需要注意,Flask这种微框架就不是一个MVC模式的,因为它没有提供Model,除非集成了SQLAlchemy之类的ORM进来。
所以大家最常见的Python Web项目的目录风格是这样的:
├── app.py
├── models # 目录
├── requirements.txt
├── static
└── views # 目录
或者:
├── app.py
├── models.py
├── requirements.txt
├── static
└── views.py
Django官方网站、《基于python的web应用开发实战》书中的项目flasky、Flask官方网站、知名的Django API框架等项目都是这种命名原则。
MVVM
MVVM(Model View ViewModel)是一种基于前端开发的架构模式,但是会写前端页面的Python Web开发显然也是有必要了解的。它的核心是提供对View和ViewModel的双向绑定,View和Model之间并没有直接的联系,而是通过ViewModel进行交互,View的变动,自动反映在ViewModel上,反之亦然,这样就保证视图和数据的一致性。
ViewModel是Model和View之间的桥梁,它的设计原则是:
为Model和View提供适配
如果有需要转换的过程,尽可能在ViewModel中做,保持Model的纯洁,View的清晰。
现在比较流行的MVVM框架是Vue.js和AngularJS。不能不感叹下,前端太能玩了。
我为什么聊MVVM呢,其实是我注意到现在有一些现象:
一些后端兼写前端的同学还在用jQuery + Template的方式在开发。
一些没什么交互的、甚至还是多页面的网站上被用上了React、Vue等方案。
当然,黑猫白猫能抓老鼠就是好猫,我说的是没有用对地方。
现在前后端交互通常是如下流程:
用户要求获取界面上的数据
通过API向后端请求数据,后端计算完成返回
界面拿到数据进行重新渲染
我们设想一个复杂的场景下,有个页面需要后端的数据来生成界面,通过在界面的某些控件输入或者触发事件的方式重新获取数据变换成其他界面。注意,整个过程页面的URL没有发生跳转。
传统的类似jQuery + Template的方式有以下痛点:
开发者在代码中大量调用相同的DOM API, 处理繁琐,操作冗余,使得代码难以维护。
大量的DOM 操作使页面渲染性能降低,加载速度变慢,影响用户体验。
当 Model 频繁发生变化,开发者需要主动更新到View ;当用户的操作导致Model发生变化,开发者同样需要将变化的数据同步到Model中, 这样的工作不仅繁琐,而且很难维护复杂多变的数据状态。
其实数据和界面的变更之间,一般都是存在对应关系的。如果能够引入一种绑定关系,经过一系列的配置过程,使得以后每次数据发生变更,界面都会自动跟着作对应变动;界面上的操作,也会自动更新到数据,那开发过程就会非常省事了,绝大部分此类操作都会转化为配置,供绑定框架用来建立数据和界面之间的关联关系。MVVM框架可以帮助你可以减少大量的DOM操作没提高渲染性能。
随着前端组件化、MVVM框架的发展,后端模板引擎来还前途嘛?
我实际工作中很多内部用到类似后台的项目,大多设计成只用基本模板index.html,其中引用了由webpack编译react/vue源码生成的javascript文件的方式,后端提供API。但是并不代表后端模板的没落:
基于SEO的考虑。后台渲染,组装页面,对SEO最友好。由于Python后端无法用NodeJS那样的「Server Rendering」方案(发现是爬虫就服务端渲染,如果是正常请求在客户端渲染,缺点是多了服务端渲染的工作)。所以必须要有必要的数据使用后端模板引擎渲染。所以要注意真正适合做SPA(单页面应用)的应用,SEO没有什么意义,因为登陆才能用,一般只需要让一些市场营销的静态页面能被SEO就好了。所以担心的前提是有冲突的。
某些场景前端无法完成。比如导出文件、秒开(复杂效果的)首屏。
后端模板对后台开发更友好。Web开发中的模板部分只是其中一部分事情,职责划分上不可能那么清晰,所以后台开发当然更喜欢在不适合做SPA的应用上使用模板来完成和其他部分(比如Model和View的维护和更新)相关的对接工作。比如Python语言的Mako模板,简直就是在写Python。
所以大家还是得好好学Jinja2、Mako吧。
django的contenttype组件的作用?
https://blog.csdn.net/Ayhan_huang/article/details/78626957
https://juejin.im/entry/581da04f128fe1005afdf618
谈谈你对restfull 规范的认识?
http://www.ruanyifeng.com/blog/2014/05/restful_api.html
接口的幂等性是什么意思?
https://www.jianshu.com/p/b09a2e9bcd29
什么是RPC?
https://www.jianshu.com/p/2accc2840a1b
Http和Https的区别?
https://juejin.im/entry/58d7635e5c497d0057fae036
为什么要使用django rest framework框架?
为什么要使用REST framework?
- 在线可视的API,对于赢得你的开发者们十分有用
验证策略涵盖了OAuth1a和OAuth2
同时支持ORM和非ORM数据源的序列化
可以配置各个环节,若无需更多强大的特性,使用一般基于方法(function-based)的视图(views)即可
大量的文档,强力的社区支持
大公司如同Mozilla和Eventbrite,也是忠实的使用者
django rest framework框架中都有那些组件?
1. 路由
- 可以通过as_view传参数,根据请求方式不同执行相应的方法
- 可以在url中设置一个结尾,类似于: .json
2. 视图
- 帮助开发者提供了一些类,并在类中提供了多个方法以供我们使用
3. 版本
- 在url中设置version参数,用户请求时候传入参数。在request.version中获取版本,根据版本不同做不同处理
4. 认证
写一个类并注册到认证类,在类的的authticate方法中编写认证逻辑。
- 认证成功(user,auth)
- raise AuthticateFaild(….)
- None
5. 权限
写一个类并注册到权限类,在类的的has_permission方法中编写认证逻辑。
- True
- False
6. 频率限制
写一个类并注册到频率类,在类的的 allow_request/wait 方法中编写认证逻辑。
1 |
|
7. 解析器
- 根据ContentType请求头,选择不同解析器对 请求体中的数据进行解析。
- POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:url-formendo…. \r\n\r\nuser=alex&age=123
- POST /index/ http1.1.\r\nhost:11.11.11.11\r\nContent-Type:application/json\r\n\r\n{….}
8. 分页
- 对从数据库中获取到的数据进行分页处理: SQL -> limit offset
django models中null和blank得区别
null
是针对数据库而言,如果 null=True
, 表示数据库的该字段可以为空
blank
是针对表单的,如果 blank=True
,表示你的表单填写该字段的时候可以不填,比如 admin
界面下增加 model
一条记录的时候。直观的看到就是该字段不是粗体
django rest framework框架中的视图都可以继承哪些类?
APIview、ViewSets、Generic views
简述 django rest framework框架的认证流程。
https://www.cnblogs.com/renpingsheng/p/9534984.html