Django项目常见面试题

本文详细介绍了Django框架中的关键概念,包括类视图、中间件、Django中间件与装饰器的区别、HTTP处理过程、DRF序列化器与反序列化器的工作原理,以及DRF视图的使用。同时,还讨论了Django项目中涉及的七牛云存储、JWT认证、Celery任务队列、跨域设置、模板语言与Vue模板的区别、jQuery操作、Shell命令、Elasticsearch搜索引擎、FastDFS分布式文件系统、定时任务、Docker使用、状态保持、Flask与Django的比较、Dumps与Loads的用途,以及Git常用命令。这些内容涵盖了Django开发中的核心知识点,对于面试和项目实践都非常有价值。
1.类视图

以函数的方式定义的视图称为函数视图,函数视图便于理解。但是遇到一个视图对应的路径提供了多种不同HTTP请求方式的支持时,便需要在一个函数中编写不同的业务逻辑,代码可读性与复用性都不佳。就比如说项目里面的注册时,需要先判断用户是get请求还是post请求,然后再根据这些请求来进行处理。其他模块如果也要判断是get还是post请求的话,也要在啪啦啪啦写一遍。

如果用了类视图就不一样了,我们可以定义一个类。类里面封装get方法和post方法,如果其他模块想要使用直接调用继承这个类视图就可以啦。就是说项目里面用的drf,他就是有很多类视图,就比如说APIView (以常规的方法实现get post put delet 等),我们可以直接继承,如果部分过程有改变,就可以继承之后再重写。代码的可读性就会比较好,就很方便。

2.django中间件

Django 在中间件中预置了六个方法,这六个方法的区别在于不同的阶段执行,对输入或输出进行干预。

1.初始化:无需任何参数,服务器响应第一个请求的时候调用一次,用于确定是否启用当前中间件。 1.def init(): 2. pass
2.处理请求前:在每个请求上调用,返回 None 或 HttpResponse 对象。 1.def process_request(request): 2. pass
3.处理视图前:在每个请求上调用,返回 None 或 HttpResponse 对象。
''1.def process_view(request, view_func, view_args, view_kwargs): 2. pass"
4.处理模板响应前:在每个请求上调用,返回实现了 render 方法的响应对象。
"1.def process_template_response(request, " response):2. pass
5.处理响应后:所有响应返回浏览器之前被调用,在每个请求上调用,返回 HttpResponse 对象。
"1.def process_response(request, " response): 2. pass
6.异常处理:当视图抛出异常时调用,在每个请求上调用,返回一个 HttpResponse 对象。
“1.def process_exception(request,exception): 2. pass”

中间件是一个用来处理Django的请求和响应的框架级别的钩子。它是一个轻量、低级别的插件系统,用于在全局范围内改变Django的输入和输出。每个中间件组件都负责做一些特定的功能。

说的直白一点中间件是帮助我们在视图函数执行之前和执行之后都可以做一些额外的操作,它本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
还可以自定义些中间件
常用5个

3.Django中间件与装饰器的区别

Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。

我们可以使用中间件,在Django处理视图的不同阶段对输入或输出进行干预。

作用:在视图函数执行之前先去进行处理,在视图函数执行之后再去进行收尾工作。
在Django创建的时候,Django默认会给我们加6个中间件。
“比如session和csrf,在视图函数执行前,我们就需要对它进行处理,可以使用装饰器来做,也可以使用中间件来处理。”
区别:

装饰器:主要是作用域问题。如果给视图函数上面添加装饰器,它能够保证这个视图的方法在执行之前或执行之后被执行。但是它仅仅适用于哪些视图添加装饰器,那些视图会有这些作用。
中间件:不会区分是哪个视图,所有的视图统统一视同仁,都会执行之前进行处理或请求之后进行处理。

如果是做一个普遍的处理,不去区分视图的话,就用middleware避免编写重复功能的代码

本质上就是一个自定义类,类中定义了几个方法,Django框架会在请求的特定的时间去执行这些方法。
可以用于登录时的黑名单验证

可以自定义一个模块文件做登录校验的中间件,然后 在settings.py里的下面列表中添加自定义的中间件来激活该中间件

详见:
Django学习(三):中间件:https://blog.youkuaiyun.com/hua1011161696/article/details/80820228

说一下中间件
“middleware是用于处理的,就比如说request对象进来,首先它会经过request的middleware进行处理,它会返回两个结果,如果它是返回None,它就会继续下去,如果它返回一个response,它就会进入response的middleware,就直接返回到前端了。如果是返回None就会进入到下面一步,就是那个url的config,对他的路由进行处理。然后后面的话就是进入view的middleware.就是说的话,他的middleware就像跟一个钩子一样,它就对整个流程里的某一步的部分处理和调整,获得的一些结果。就大概是这个情况。”

4. django处理http过程

一个 HTTP 请求,首先被转成一个 HttpRequest对象,然后该对象被传递给Request中间件处理,如果该中间件返回了Response,则直接传递给 Response 中间件做收尾处理。
否则的话 Request 中间件将访问 URL 配置,确定哪个 view 来处理,在确定了哪个 view 要执行,但是还没有执行该 view 的时候,系统会把 request 传递给view中间件处理器进行处理,如果该中间件返回了Response,那么该 Response 直接被传递给Response中间件进行后续处理,
否则将执行确定的view函数处理并返回Response,
在这个过程中如果引发了异常并抛出,会被 Exception 中间件处理器进行处理。

>一个http请求,								
初始化转为HttpRequest对象====》到request中间件处理===》返回response===》response中间件处理								
							|
							|
							访问url配置,确定view来处理request
							|
							|
							view的中间件进行处理===》返回response===》response中间件处理
							|
							|出现异常===》exception中间件进行处理
							|
							view函数处理并返回response			

5.drf序列化器与反序列化器

序列化:

将对象的状态信息转换为可以存储或传输的形式的过程。(百度定义)
对应到drf中,序列化即把模型对象转换为字典形式, 再返回给前端,主要用于输出 序列化返回

序列化器,就是对数据进行校验、对数据对象进行转化
将Django中的模型类对象装换为JSON字符串,这个转换过程我们称为序列化

反序列化:

把其他格式转化为程序中的格式。

对应drf中接收前段数据经过验证转为Python中的字典,主要用于输入,接收前段数据

反序列化存储

使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
将JSON字符串转换为Django中的模型类对象,这个过程我们称为反序列化。
loads

6.drf视图

drf

在前后端分离的应用模式中,后端仅返回前端所需的数据,不再渲染HTML页面,不再控制前端的效果。至于前端用户看到什么效果,从后端请求的数据如何加载到前端中,都由前端自己决定,网页有网页的处理方式,App有App的处理方式,但无论哪种前端,所需的数据基本相同,后端仅需开发一套逻辑对外提供数据即可。
在前后端分离的应用模式中 ,前端与后端的耦合度相对较低。

在前后端分离的应用模式中,我们通常将后端开发的每个视图都称为一个接口,或者API,前端通过访问接口来对数据进行增删改查。

RESTful是一种开发理念。维基百科说:REST是设计风格而不是标准
常用的HTTP动词有下面四个(括号里是对应的SQL命令)。

GET(SELECT):从服务器取出资源(一项或多项)。
POST(CREATE):在服务器新建一个资源。
PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)。
DELETE(DELETE):从服务器删除资源。

创建序列化器来处理数据,使用serializers.ModelSerializerclass创建序列化器, 导入Meta类,直接用序列化器来做查询器和序列化与反序列化操作。

7.drf-视图的理解
  1. 类视图
    写视图的步骤:
  2. 数据库查询, 2. 构建序列化器, 进行序列化操作, 返回数据
    一. 两大基类

1 APIView (以常规的方法实现get post put delet 等)
继承与VIew, 可以帮助我们处理request和response
可以捕获异常处理, 处理成适合的响应信息
进行第三patch()分发前, 对用户进行身份验证, 权限验证, 流量控制

支持的定义属性:
authentication_classes 列表或元祖,身份认证类
permissoin_classes 列表或元祖,权限检查类
throttle_classes 列表或元祖,流量控制类

2 GenericsAPIView 继承于 APIView
支持定义的属性:
列表视图与详情视图通用:
queryset 列表视图的查询集 查询单一, 所有
serializer_class 视图使用的序列化器 指明序列化器
列表视图使用:
pagination_class 分页控制类
filter_backends 过滤控制后端
详情页视图使用:
lookup_field 查询单一数据库对象时使用的条件字段,默认为’pk’
lookup_url_kwarg 查询单一数据时URL中的参数关键字名称,默认与look_field相同

提供的方法:
列表视图与详情视图通用:

get_queryset(self)

返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写
二. 五个扩展类

  1. ListModelMixin
    查询所有数据的扩展类, 该视图提供 list(request, *args, **kwargs) 实现列表视图, 返回200
    list方法对数据进行过滤和分页. -------> 查询出过滤分页后所有的数据
  2. CreateModelMixin
    创建视图的扩展类, 该视图提供 create(request, *args, **kwargs)来创建资源的视图, 返回201
    序列化验证失败, 返回400错误
  3. RetrieveModelMixin
    详情视图扩展类, 该视图提供 retrieve(request, *args, **kwargs), 快速的返回一个详情页
    存在查询对象返回200, 不存在就是404
  4. UpdateModelMixin
    更新视图扩展类, 提供update(request, *args, *kwargs), 更新一个存在的对象
    同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
    成功返回200,序列化器校验数据失败时,返回400错误。
  5. DestroyModelMixin
    删除视图扩展类, 提供destroy(request, *args, **kwargs)方法, 删除一个存在的数据对象
    成功返回 204 , 不存在返回 404

三. 视图集 ViewSet
使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:

list() 提供一组数据
retrieve() 提供单个数据
create() 创建数据
update() 保存数据
destory() 删除数据

ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上

8.七牛云

就是服务器收到浏览器的上传图片请求,然后接受请求,读取图片,校验图片,调用七牛云sdk,最后再把图片名称存入数据库里。它是安装这个第三方包,然后根据SDK文档里有一些示例代码,把这些实例代码进行封装成方法,然后用request.files.get(’’).read()得到上传的图片,再用import导入包,调用storage方法,里面有put_file方法将图片文件上传到七牛云里。并设置用户模型数据,将文件信息保存到数据库里。

9.jwt

在项目中,jwt token认证机制是对session认证机制的替代,基于之前的session认证机制,存在以下问题:

​ 1)session信息存储在服务器端,如果登录用户过多,会占用过多服务器的空间;
2)session依赖于cookie,session信息的标识保存在cookie中,如果cookie被截获,可能会造成 CSRF(跨站请求伪造攻击);
3)session认证不适合的分布式站点的应用场景。

1)对于jwt token的认证机制,在用户登录时,服务器会签发(生成)一个jwt token字符串;
2)服务器在响应时将jwt token数据返回给客户端,客户端需保存jwt token数据;
3)之后客户端在请求服务器时,如果需要进行用户的认证,需要将jwt token数据通过请求头传递给服务器,服务器会核验jwt token数据的有效性。

jwt token字符串组成`:

包含3部分内容,用.隔开。
1)头部(header):包含token类型和加密算法信息,使用base64编码生成字符串。
2)载荷(payload):保存有效的数据,通常还包含token的有效时间,使用base64编码生成字符串。
3)签名(signature):防止jwt token被伪造,由服务器在生成jwt token时,将header和payload内容拼接用.隔开,然后使用密钥加密生成。 签名有三部分组成,包括把头部、载荷、私钥(私钥是django项目一创建出来就出现在配置文件里的)再用base64编码,构成最终的jwt.

  • jwt认证的特点和使用:
    ​ 1)jwt token由服务器生成,交给客户端进行存储,不占用服务器的存储空间;

    2)适合于分布式站点的应用场景。

    ​ 3)使用时payload中不要存储敏感信息,因为这部分内容很容易被客户端解码。

    4)服务器端的密钥需要保存好,泄露密钥之后jwt token数据可以被随意伪造。

我们保存jwt,token在浏览器本地存储中,返回给前端,前端保存token。私钥是django项目一创建出来就出现在配置文件里的)再用base64编码,构成最终的jwt.

修改密码怎样退出登录:

做一个判断,看密码是否修改,修改的话就把taken加入黑名单。每次都检验黑名单。先判断是否存在黑名单里,如果存在,就退出登录。

jwt注销登录

jwt最大的问题就在于后台没有存储用户状态,用户退出的话只是客户端删掉了token,然而此token在有效期内还是有效的。那么最麻烦的就是怎么让一个token在用户注销后失效,以及后台强制退出,这个jwt是没办法的,因为jwt的无状态和用户状态维护是个矛盾冲突的话题。如果要解决就要建立一个黑名单,也就是把用户注销后的token放到redis里,然后每次校验黑名单(这里还是用到了数据库)。

说出CSRF 攻击的原理和防范措施

a)攻击原理:
i.用户C访问正常网站A时进行登录,浏览器保存A的cookie
ii.用户C再访问攻击网站B,网站B上有某个隐藏的链接或者图片标签会自动请求网站A的URL地址,例如表单提交,传指定的参数
iii.而攻击网站B在访问网站A的时候,浏览器会自动带上网站A的cookie
iv.所以网站A在接收到请求之后可判断当前用户是登录状态,所以根据用户的权限做具体的操作逻辑,造成网站攻击成功

b)防范措施:
i.在请求头的里面添加一个随机值做为参数
ii.在响应的cookie里面也设置该随机值
iii.那么用户C在正常提交表单的时候会默认带上表单中的随机值,浏览器会自动带上cookie里面的随机值,那么服务器下次接受到请求之后就可以取出两个值进行校验
iv.而对于网站B来说网站B在提交表单的时候不知道该随机值是什么,所以就形成不了攻击
也可以用来设置避免表单的重复提交

10.Celery 分布式任务队列

情景:用户发起request,并等待response返回。

在本些views中,可能需要执行一段耗时的程序,那么用户就会等待很长时间,造成不好的用户体验,比如发送邮件、手机验证码等。
使用 celery 后,情况就不一样了。解决:将耗时的程序放到 celery 中执行。
将多个耗时的任务添加到队列 queue 中,也就是用 redis 实现 broker 中间人,然后用多个 worker 去监听队列里的任务去执行。

celery通过消息进行通信,通常使用一个叫Broker(中间人)来协client(任务的发出者)和worker(任务的处理者). clients发出消息到队列中,broker将队列中的信息派发给worker来处理。

任务队列是一种跨线程、跨机器工作的一种机制.
celery保存在redis里面

11.怎么实现跨域

安装
pip install django-cors-headers
添加应用
INSTALLED_APPS = (

‘corsheaders’,

)

中间层设置
MIDDLEWARE = [
‘corsheaders.middleware.CorsMiddleware’,

]

添加白名单
#CORS
CORS_ORIGIN_WHITELIST = (
‘127.0.0.1:8080’,
‘localhost:8080’,
‘www.meiduo.site:8080’,
‘api.meiduo.site:8000’
)
CORS_ALLOW_CREDENTIALS = True # 允许携带cookie

12.django模板与Vue模板语法区别

diango模板 (templates)用的不多
像Vue里面的话 就是胡子语法 “Mustache”语法 (双大括号) 的文本插值
多了空格的话在Django里会报错

扩:django模板指在工程中创建模板目录templates。
胡子语法指的是{{data}}
vue通过axios来连接

Vue实例
每个 Vue 应用都是通过实例化一个新的 Vue对象开始的:

window.onload = function(){
var vm = new Vue({
    el:'#app',
    data:{message:'hello world!'}
});
}    
......
<div id="app">{{ message }}</div>

其中,el属性对应一个标签,当vue对象创建后,这个标签内的区域就被vue对象接管,在这个区域内就可以使用vue对象中定义的属性和方法。

vue.js没有集成ajax功能,要使用ajax功能,可以使用vue官方推荐的axios.js库来做ajax的交互。

13.jequery 里通过id怎么取值

先定位到节点,然后用val 就是val这个方法 如果是本身默认的话,就用val,如果是你自己那个的话, 就用attr这个方法
用$("#id").val()获取value值
$("#id").attr(“value”)

14.shell

Django的manage工具提供了shell命令,帮助我们配置好当前工程的运行环境(如连接好数据库等),以便可以直接在终端中执行测试python语句。

15.es搜索引擎`:

Elasticsearch(简称es)是java语言实现的一个开源的搜索引擎,是目前全文检索的首选。通过搜索引擎进行数据查询时,搜索引擎并不是直接在数据库中进行查询,而是会对数据库中的数据进行一遍预处理,单独建立起一份索引结构数据。在通过搜索引擎搜索时,搜索引擎将关键字在索引数据中进行快速对比查找,进而找到数据的真实存储位置。

分布式实时文件存储,并将每一个字段都编入索引,使其可以被搜索。
可实现亿级数据实时查询
实时分析的分布式搜索引擎。
可以扩展到上百台服务器,处理PB级别的结构化或非结构化数据。

在项目里,使用Docker搭建es搜索引擎服务器并使用haystack对接es搜索引擎来实现商品的搜索功能。
haystack 全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理

16.fastdf分布式文件系统

包括tracker和storage。
FastDFS 架构包括 Tracker server 和 Storage server。客户端请求 Tracker server 进行文 件上传、下载,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。

有个sdk文件,然后import导入,后面再用request.files.get(’’).read()得到上传的图片,调用里面的方法,里面有put_file方法将图片文件上传到fastdf里面

17.定时任务

安装
pip install django-crontab
添加应用
INSTALLED_APPS = [

‘django_crontab’, # 定时任务

]
设置任务的定时时间

可以在文件夹里面看到这些文件

开启定时任务
添加定时任务到系统中
python manage.py crontab add
显示已经激活的定时任务
python manage.py crontab show
移除定时任务
python manage.py crontab remove

18.docker你用的挺熟的嘛

docker的话一般提起来都喜欢和虚拟机联系起来,提起docker的话,我脑海里有3个关键字,就是镜像、容器、仓库,就是它会把一些镜像在虚拟机里运作起来,那么它就是一个容器。为什么说它是一个仓库呢,就是它负责管理存储这些镜像文件。然后docker它有一个很大的好处就是,对于我们开发人员来说,这个代码在我这里能跑,但是在运维那里就跑不了,然后运维就说你的代码有问题,但是再试的话就又能跑了,没有问题。但是我们用了docker的话就不会出现这种问题,因为它的环境是一样的。所以运维也蛮喜欢用这个的,因为说用docker的话它会把你的运行程序隔离起来,就不会有影响。它是用go写的。

19.保持状态,一个网页到另外一个网页,就比如说从qq空间到邮箱,都是登录的

在登录之前给个校验,如果检验通过的话,就登录。。。?(未完待续)

20.flask与Django有什么区别

个人更倾向flask,因为它更方便,更灵活,用什么就装什么。不想django那样,都放在那里。就好比你买辆车吧,django就是什么车胎发动机都给你定下来装好了,而flask的话我可以改改发动机呀改改轮胎呀什么的,根据个人的需求来定制化操作。flask更轻便。

21.dumps与loads

项目接口里用到
dumps:将dict(字典)转换为str(字符串)。
loads:用于将str(字符串)转换为dict(字典)

22.用过的算法

SHA-1(项目里jwt用的)、

23.说出git常用命令并说出该命令的作用

a)作用:对源代码进行分布式,版本控制,方便跟踪源代码的修改过程,备份源代码,在团队开发中经常使用
b)常用命令:
i.git init 初始化本地git仓库
ii.git add . 将当前工作区的所有文件添加到暂存区
iii.git commit -m “”将当前暂存区文件添加到本地仓库进行版本管理
iv.git push 将本地仓库内容添加到远程仓库中
v.git pull 将远程仓库代码拉取到本地
vi.git clone 拷贝远程仓库内容到本地

24.Django框架优化?

对一个后端开发程序员来说,提升性能指标主要有两个一个是并发数,另一个是响应时间网站性能的优化一般包括 web 前端性能优化,应用服务器性能优化,存储服务器优化。

对前端的优化主要有:
1.减少 http 请求,减少数据库的访问量,比如使用雪碧图。
2.使用浏览器缓存,将一些常用的 css,js,logo 图标,这些静态资源缓存到本地浏览器,通过设置 http 头中的 cache-control 和 expires 的属性,可设定浏览器缓存,缓存时间可以自定义。
3 对 html,css,javascript 文件进行压缩,减少网络的通信量。

对我个人而言,我做的优化主要是以下三个方面:
1.合理的使用缓存技术,对一些常用到的动态数据,比如首页做一个缓存,或者某些常用的数据做个缓存,设置一定得过期时间,这样减少了对数据库的压力,提升网站性能。
2.使用 celery 消息队列,将耗时的操作扔到队列里,让 worker 去监听队列里的任务,实现异步操作,比如发邮件,发短信。
3.就是代码上的一些优化,补充:nginx 部署项目也是项目优化,可以配置合适的配置参数,提升效率,增加并发量。
4.如果太多考虑安全因素,服务器磁盘用固态硬盘读写,远远大于机械硬盘,这个技术现在没有普及,主要是固态硬盘技术上还不是完全成熟, 相信以后会大量普及。
5.另外还可以搭建服务器集群,将并发访问请求,分散到多台服务器上处理。
6.最后就是运维工作人员的一些性能优化技术了。

其他版本

首先,我会从代码这块着手。用debug调试,到前端页面,按f12,看看模块的使用是不是合理,不合理的话就修改下代码。相对来说,改后端代码是比较简单的操作。如果一切都没没问的话,
其次呢,我就会考虑从数据库这块优化。比方说sql语句,分析下慢查询,看看语句的耗时是否合理。
最后呢,才会考虑一些部署问题,比方说搭建集群,nginx反向代理,数据库主从同步读写分离,使用就缓存技术等。

25.nginx

Nginx
采用 C 语言编写
实现分流、转发、负载均衡

服务器
WSGI(Web Server Gateway Interface),翻译为Python web服务器网关接口,即Python的Web应用程序(如Flask)和Web服务器(如Nginx)之间的一种通信协议。也就是说,如果让你的Web应用在任何服务器上运行,就必须遵循这个协议。

那么实现WSGI协议的web服务器有哪些呢?

就比如uWSGI与gunicorn。两者都可以作为Web服务器。可能你在许多地方看到的都是采用Nginx + uWSGI(或gunicorn)的部署方式。实际上,直接通过uWSGI或gunicorn直接部署也是可以让外网访问的,那你可能会说,那要Nginx何用?别急,那么接来下介绍另一个Web服务器——Nginx

Nginx作为一个高性能Web服务器,具有负载均衡、拦截静态请求、高并发…等等许多功能,你可能要问了,这些功能和使用Nginx + WSGI容器的部署方式有什么关系?

首先是负载均衡,如果你了解过OSI模型的话,其实负载均衡器就是该模型中4~7层交换机中的一种,它的作用是能够仅通过一个前端唯一的URL访问分发到后台的多个服务器,这对于并发量非常大的企业级Web站点非常有效。在实际应用中我们通常会让Nginx监听(绑定)80端口,通过多域名或者多个location分发到不同的后端应用。

其次是拦截静态请求,简单来说,Nginx会拦截到静态请求(静态文件,如图片),并交给自己处理。而动态请求内容将会通过WSGI容器交给Web应用处理;

Nginx还有其他很多的功能,这里便不一一介绍。那么前面说了,直接通过uWSGI或gunicorn也可以让外网访问到的,但是鉴于Nginx具有高性能、高并发、静态文件缓存、及以上两点、甚至还可以做到限流与访问控制,所以选择Nginx是很有必要的;

这里可以说明,如果你选择的架构是:Nginx + WSGI容器 + web应用,WSGI容器相当于一个中间件;如果选择的架构是uWSGI + web应用,WSGI容器则为一个web服务器

26.说说 nginx 和 uWISG 服务器之间如何配合工作的?

首先浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型.
如果是静态资源,直接读取静态资源返回给浏览器.
如果请求的是动态资源就转交给 uwsgi服务器,uwsgi 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 Django 框架,Django 框架下的应用进行逻辑处理后,将返回值发送到 uwsgi 服务器,然后 uwsgi 服务器再返回给 nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户。

27.谈一下你对 uWSGI 和 nginx 的理解
  1. uWSGI 是一个 Web 服务器,它实现了 WSGI 协议、uwsgi、http 等协议。Nginx 中
    HttpUwsgiModule 的作用是与 uWSGI 服务器进行交换。WSGI 是一种 Web 服务器网关接口。它是一个 Web 服务器(如 nginx,uWSGI 等服务器)与 web 应用(如用 Flask 框架写的程序)通信的一种规范。
    要注意 WSGI / uwsgi / uWSGI 这三个概念的区分。
    WSGI 是一种通信协议。
    uwsgi 是一种线路协议而不是通信协议,在此常用于在 uWSGI 服务器与其他网络服务器的数据通信。
    uWSGI 是实现了 uwsgi 和 WSGI 两种协议的 Web 服务器。
  2. nginx 是一个开源的高性能的 HTTP 服务器和反向代理:
    1.作为 web 服务器,它处理静态文件和索引文件效果非常高;
    2.它的设计非常注重效率,最大支持 5 万个并发连接,但只占用很少的内存空间;
    3.稳定性高,配置简洁;
    4.强大的反向代理和负载均衡功能,平衡集群中各个服务器的负载压力应用。
28.Gunicorn

Gunicorn(绿色独角兽)是一个Python WSGI的HTTP服务器
从Ruby的独角兽(Unicorn )项目移植
该Gunicorn服务器与各种Web框架兼容,实现非常简单,轻量级的资源消耗
Gunicorn直接用命令启动,不需要编写配置文件
django+gunicorn+nginx理解
我先尝试讲一下我对django + gunicorn + nginx 这三兄弟的理解。首先我们知道,我们访问网站,就是去网络上的一台电脑里访问某个路径下的某个文件,那django的作用主要是做(生产)这个文件,拿一家餐馆来讲,我认为django就是这个餐馆的厨师,他负责做菜,当规模很小的时候,比如路边卖鸡蛋饼的大妈,因为客人不多,所以可以自己问客人要什么,然后再自己做,这就是django和自带的runserver所做的事情;那当规模变大了,比如普通餐馆,客人很多,厨师做菜都来不急了,根本没时间去问客人要什么,所以这个时候我们就需要服务员了,服务员去记录客人要什么,然后跟厨房讲,接着从厨房拿菜给客人,而在这里,gunicorn就是这个服务员;当规模更大一些的时候,每分钟都有几百个人(现实中来讲这已经是多到爆炸了吧)要进餐馆吃饭,你在餐馆里安排再多的服务员也不能处理完这么多客人的请求,而且餐馆的空间是有限的,服务员也占空间,多了放不下,所以这个时候怎么办呢,答案是在餐馆门口安排咨客,有序地引导客人进入餐馆,也可以在门口就帮客人点好菜,提高整体效率,Nginx就扮演了咨客这个角色。
新闻咨询可以用flask+nginx+gunicorn
商城可以用django+nginx+uwsgi

29.Python 中三大框架各自的应用场景?

django:主要是用来快速开发的,他的亮点就是快速开发,节约成本,正常的并发量不过 10000, 如果要实现高并发的话,就要对 django 进行二次开发,比如把整个笨重的框架给拆掉,自己写 socket 实现 http 的通信,底层用纯 c,c++写提升效率,ORM 框架给干掉,自己编写封装与数据库交互的框架,因为啥呢,ORM 虽然面向对象来操作数据库,但是它的效率很低,使用外键来联系表与表之间的查询;

flask:轻量级,主要是用来写接口的一个框架,实现前后端分离,提升开发效率,Flask 本身相当于一个内核,其他几乎所有的功能都要用到扩展(邮件扩展 Flask-Mail,用户认证 Flask-Login),都需要用第三方的扩展来实现。比如可以用 Flask-extension 加入ORM、窗体验证工具,文件上传、身份验证等。Flask 没有默认使用的数据库,你可以选择 MySQL,也可以用 NoSQL。
其 WSGI 工具箱采用 Werkzeug(路由模块),模板引擎则使用 Jinja2。这两个也是 Flask 框架的核心。
Python最出名的框架要数 Django,此外还有 Flask、Tornado 等框架。虽然 Flask 不是最出名的框架,但是 Flask 应该算是最灵活的框架之一,这也是 Flask 受到广大开发者喜爱的原因。

Tornado: Tornado 是一种 Web 服务器软件的开源版本。Tornado和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻塞式服务器,而且速度相当快。
得利于其非阻塞的方式和对 epoll 的运用,Tornado 每秒可以处理数以千计的连接,因此 Tornado 是实时 Web 服务的一个 理想框架。

epoll是Linux内核为处理大批量文件描述符而作了改进的poll,是Linux下多路复用IO接口select/poll的增强版本,它能显著提高程序在大量并发连接中只有少量活跃的情况下的系统CPU利用率。另一点原因就是获取事件的时候,它无须遍历整个被侦听的描述符集,只要遍历那些被内核IO事件异步唤醒而加入Ready队列的描述符集合就行了。epoll除了提供select/poll那种IO事件的水平触发(Level Triggered)外,还提供了边缘触发(Edge Triggered),这就使得用户空间程序有可能缓存IO状态,减少epoll_wait/epoll_pwait的调用,提高应用程序效率。

30.单元测试

单元测试就是开发者编写一小段代码,检验目标代码的功能是否符合预期。单元测试主要面向一些功能单一的模块进行。
在Web开发过程中,单元测试实际上就是一些“断言”(assert)代码。

断言就是判断一个函数或对象的一个方法所产生的结果是否符合你期望的那个结果。 python中assert断言是声明布尔值为真的判定,如果表达式为假会发生异常。单元测试中,一般使用assert来断言结果。

比如登录、数据库等。对登录进行测试时,导入unittest测试框架,json,测试模块,定义一个类,继承unittest.TestCase,再使用setup和teardown方法,定义测试的预期情况的方式(以test开头),包括 “”“测试用户名与密码为空的情况[当参数不全的话,返回errcode=-2]”"",""“测试用户名和密码错误的情况[当登录名和密码错误的时候,返回 errcode = -1]”"",里面会用到 self.assertIn,self.assertEqual。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值