Django面试问题
Http 请求方法
GET
- 向特定的路径资源发出请求
POST
向指定路径资源提交数据进行处理请求(一般用于提交表单或者上传文件)
数据被包含在请求体中,POST请求可能会导致新的资源的建立和/或已有资源的修改。
OPTIONS
- 返回服务器支持的方法
HEAD
- 只会返回响应头部,没有响应实体
PUT
- 从客户端上传文件取代指定内容
DELETE
- 删除指定内容
TRACE
- 主要用于测试
CONNECT
- 预留给能够将链接改为管道方式的代理服务
谈谈你对HTTP协议的认识
- 应用层协议
- 基于TCP/IP协议
- 基于请求-响应模式
Django请求生命周期
- 一般是用户通过浏览器向我们的服务器发起一个请求(request),这个请求回去访问视图函数,(如果不涉及到数据调用,那么这个时候视图函数返回一个模板也就是一个网页给用户),视图函数调用模型,模型去数据库查找数据,然后逐级返回,视图函数把返回的数据填充到模板中空格中,最后返回网页给用户
Django中间件与装饰器的区别
- Django中的中间件是一个轻量级、底层的插件系统,可以介入Django的请求和响应处理过程,修改Django的输入或输出。中间件的设计为开发者提供了一种无侵入式的开发方式,增强了Django框架的健壮性。
- 说一下中间件:
“middleware是用于处理的,就比如说request对象进来,首先它会经过request的middleware进行处理,它会返回两个结果,如果它是返回None,它就会继续下去,如果它返回一个response,它就会进入response的middleware,就直接返回到前端了。如果是返回None就会进入到下面一步,就是那个url的config,对他的路由进行处理。然后后面的话就是进入view的middleware.就是说的话,他的middleware就像跟一个钩子一样,它就对整个流程里的某一步的部分处理和调整,获得的一些结果。就大概是这个情况。”
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
drf序列化和反序列化
- 序列化
对应到drf中,序列化即把模型对象转换为字典形式, 再返回给前端,主要用于输出 序列化返回
序列化器,就是对数据进行校验、对数据对象进行转化
将Django中的模型类对象装换为JSON字符串,这个转换过程我们称为序列化。
- 反序列化
对应drf中接收前段数据经过验证转为Python中的字典,主要用于输入,接收前段数据
反序列化存储
使用序列化器进行反序列化时,需要对数据进行验证后,才能获取验证成功的数据或保存成模型类对象。
在获取反序列化的数据前,必须调用is_valid()方法进行验证,验证成功返回True,否则返回False。
将JSON字符串转换为Django中的模型类对象,这个过程我们称为反序列化。
什么是wsgi,uwsgi,uWSGI,nginx?
WSGI:
# web服务器网关接口,是一套协议。用于接收用户请求并将请求进行初次封装,然后将请求交给web框架
# 实现wsgi协议的模块:
# 1.wsgiref,本质上就是编写一个socket服务端,用于接收用户请求(django)
# 2.werkzeug,本质上就是编写一个socket服务端,用于接收用户请求(flask)
uwsgi:
# 与WSGI一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
# uwsgi 是一种线路协议而不是通信协议,在此常用于在 uWSGI 服务器与其他网络服务器的数据通信。
uWSGI:
# 是一个web服务器,实现了WSGI协议,uwsgi协议,http协议,
nginx 是一个开源的高性能的 HTTP 服务器和反向代理:
1.作为 web 服务器,它处理静态文件和索引文件效果非常高;
2.它的设计非常注重效率,最大支持 5 万个并发连接,但只占用很少的内存空间;
3.稳定性高,配置简洁;
4.强大的反向代理和负载均衡功能,平衡集群中各个服务器的负载压力应用
nginx 与uWISG服务器之间如何配合工作
首先浏览器发起 http 请求到 nginx 服务器,Nginx 根据接收到请求包,进行 url 分析,判断访问的资源类型.
如果是静态资源,直接读取静态资源返回给浏览器.
如果请求的是动态资源就转交给 uwsgi服务器,uwsgi 服务器根据自身的 uwsgi 和 WSGI 协议,找到对应的 Django 框架,Django 框架下的应用进行逻辑处理后,将返回值发送到 uwsgi 服务器,然后 uwsgi 服务器再返回给 nginx,最后 nginx将返回值返回给浏览器进行渲染显示给用户。
django路由系统中name的作用?
- 用于反向解析路由,相当于给url取个别名,只要这个名字不变,即使对应的url改变通过该名字也能找到该条url
Django内置组件
- 1.Admin是对model中对应的数据表进行增删改查提供的组件
2.model组件:负责操作数据库
3.form组件:1.生成HTML代码 2.数据有效性校验 3 .校验信息返回并展示
4.ModelForm组件即用于数据库操作,也可用于用户请求的验证
列举django中间件的5个方法?
- 1.process_request : 请求进来时,权限认证
2.process_view : 路由匹配之后,能够得到视图函数
3.process_exception : 异常时执行
4.process_template_responseprocess : 模板渲染时执行
5.process_response : 请求有响应时执行
Django重定向是如何实现的?用的什么状态码?
- 1.使用HttpResponseRedirect
from django.http import HttpResponseRedirect
2.使用redirect和reverse
状态码:301和302
301:永久跳转
302:临时重定向。比如登录时,检查登录状态,未登录重定向到登录页面。
django中csrf的实现机制
- 第一步:django第一次响应来自某个客户端的请求时,后端随机产生一个token值,把这个token保存在SESSION状态中;同时,后端把这个token放到cookie中交给前端页面;
第二步:下次前端需要发起请求(比如发帖)的时候把这个token值加入到请求数据或者头信息中,一起传给后端;Cookies:{csrftoken:xxxxx}
第三步:后端校验前端请求带过来的token和SESSION里的token是否一致;
基于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"``)},
Django本身提供了runserver,为什么不能用来部署?(runserver与uWSGI的区别)
1.runserver方法是调试 Django 时经常用到的运行方式,它使用Django自带的WSGI Server 运行,主要在测试和开发中使用,并且 runserver 开启的方式也是单进程 。
2.uWSGI是一个Web服务器,它实现了WSGI协议、uwsgi、http 等协议。注意uwsgi是一种通信协议,而uWSGI是实现uwsgi协议和WSGI协议的 Web 服务器。
uWSGI具有超快的性能、低内存占用和多app管理等优点,并且搭配着Nginx就是一个生产环境了,能够将用户访问请求与应用 app 隔离开,实现真正的部署 。
相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。
only和defer的区别?
#only:从数据库中只取指定字段的内容
#defer:指定字段的内容不被检索
列举django orm 中所有的方法
all(): 查询所有结果
filter(**kwargs): 它包含了与所给筛选条件相匹配的对象。获取不到返回None
get(**kwargs): 返回与所给筛选条件相匹配的对象,返回结果有且只有一个。获取不到会抱胸如果符合筛选条件的对象超过一个或者没有都会抛出错误。
exclude( order_by(*field): 对查询结果排序
reverse(): 对查询结果反向排序
count(): 返回数据库中匹配查询(QuerySet)的对象数量。
first(): 返回第一条记录
last(): 返回最后一条记录
exists(): 如果QuerySet包含数据,就返回True,否则返回False
values(*field): 返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系 model的实例化对象,而是一个可迭代的字典序列
values_list(*field): 它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
distinct(): 从返回结果中剔除重复纪录
select_related和prefetch_related的区别?
#有外键存在时,可以很好的减少数据库请求的次数,提高性能
#select_related通过多表join关联查询,一次性获得所有数据,只执行一次SQL查询
#prefetch_related分别查询每个表,然后根据它们之间的关系进行处理,执行两次查询
如何使用django orm批量创建数据?
bulk_create()
objs=[models.Book(title="图书{}".format(i+15)) for i in range(100)]
models.Book.objects.bulk_create(objs)
django的Form和ModeForm的作用?
- Form
- 在前端生成HTML代码
- 对数据做校验
- 返回校验信息并展示
- ModeFor
- 根据模型生成Form组件,并且可以操作数据库
django-debug-toolbar的作用?
- 1.是django的第三方工具包,给django扩展了调试功能。包括查看sql语句,db查询次数,request,headers等
解释orm中 db first 和 code first的含义?
- 数据持久化的方式:
- db first基于已存在的数据库,生成模型
- code first基于已存在的模型,生成数据库库
什么是RPC?
- 远程过程调用 (RPC) 是一种协议,程序可使用这种协议向网络中的另一台计算机上的程序请求服务
- 1.RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。
- 2.首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。
- 3.在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,
- 4.最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
rest frameWork框架
能自动生成符合 RESTful 规范的 API
1.在开发REST API的视图中,虽然每个视图具体操作的数据不同,但增、删、改、查的实现流程基本一样,这部分的代码可以简写
2.在序列化与反序列化时,虽然操作的数据不同,但是执行的过程却相似,这部分的代码也可以简写REST framework可以帮助简化上述两部分的代码编写,大大提高REST API的开发速度组件
1.序列化组件:serializers 对queryset序列化以及对请求数据格式校验
2.路由组件routers 进行路由分发
3.视图组件ModelViewSet 帮助开发者提供了一些类,并在类中提供了多个方法
4.认证组件 写一个类并注册到认证类(authentication_classes),在类的的authticate方法中编写认证逻
5.权限组件 写一个类并注册到权限类(permission_classes),在类的的has_permission方法中编写认证逻辑。
6.频率限制 写一个类并注册到频率类(throttle_classes),在类的的allow_request/wait 方法中编写认证逻辑
7.解析器 选择对数据解析的类,在解析器类中注册(parser_classes)
8.渲染器 定义数据如何渲染到到页面上,在渲染器类中注册(renderer_classes)
9.分页 对获取到的数据进行分页处理, pagination_class
10.版本 版本控制用来在不同的客户端使用不同的行为
在url中设置version参数,用户请求时候传入参数。在request.version中获取版本,根据版本不同 做不同处理如何实现的用户访问频率控制
- 使用IP/用户账号作为键,每次的访问时间戳作为值,构造一个字典形式的数据,存起来,每次访问时对时间戳列表的元素进行判断,把超时的删掉,再计算列表剩余的元素数就能做到频率限制了
匿名用户:使用IP控制,但是无法完全控制,因为用户可以换代理IP登录用户。使用账号控制,但是如果有很多账号,也无法限制
- 使用IP/用户账号作为键,每次的访问时间戳作为值,构造一个字典形式的数据,存起来,每次访问时对时间戳列表的元素进行判断,把超时的删掉,再计算列表剩余的元素数就能做到频率限制了
PV和UV
- pv:页面访问量,没打开一次页面PV计算+1,页面刷新也是
UV:独立访问数,一台电脑终端为一个访客
什么是跨域以及解决方法:
#跨域: # 浏览器从一个域名的网页去请求另一个域名的资源时,浏览器处于安全的考虑,不允许不同源的请求 #同源策略: # 协议相同 # 域名相同 # 端口相同 #处理方法: # 1.通过JSONP跨域 # JSON是一种数据交换格式 # JSONP是一种非官方的跨域数据交互协议 # jsonp是包含在函数调用中的json # script标签不受同源策略的影响,手动创建一个script标签,传递URL,同时传入一个回调函数的名字 # 服务器得到名字后,返回数据时会用这个函数名来包裹住数据,客户端获取到数据之后,立即把script标签删掉 # 2.cors:跨域资源共享 # 使用自定义的HTTP头部允许浏览器和服务器相互通信 # 1.如果是简单请求,直接设置允许访问的域名: # 允许你的域名来获取我的数据 # response['Access-Control-Allow-Origin'] = "*" # 2.如果是复杂请求,首先会发送options请求做预检,然后再发送真正的PUT/POST....请求 # 因此如果复杂请求是PUT等请求,则服务端需要设置允许某请求 # 如果复杂请求设置了请求头,则服务端需要设置允许某请求头 #简单请求: # 一次请求 #非简单请求: # 两次请求,在发送数据之前会先发一次请求用于做“预检”, # 只有“预检”通过后才再发送一次请求用于数据传输。
#只要同时满足以下两大条件,就属于简单请求。
# (1) 请求方法是以下三种方法之一:HEAD GET POST
# (2)HTTP的头信息不超出以下几种字段:
# Accept
# Accept-Language
# Content-Language
# Last-Event-ID
# Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、 text/plain
#JSONP和CORS:
# 1.JSONP只能实现GET请求,而CORS支持所有类型的HTTP请求
# 2.jsonp需要client和server端的相互配合
# 3.cors在client端无需设置,server端需要针对不同的请求,来做head头的处理
如何实现用户的登陆认证
1.cookie session
2.token 登陆成功后生成加密字符串
3.JWT:json wed token缩写 它将用户信息加密到token中,服务器不保存任何用户信息
服务器通过使用保存的密钥来验证token的正确性