面试题面试题!!!
Django的生命周期
1、当用户在浏览器输入url,此时浏览器会生成请求头和请求体随之发送给服务端。
2、url经过Django中的wsgi时完成请求对象创建
3、经过Django的中间件,到路由系统匹配路由
4、完成匹配后进入相应的view视图,执行相关代码返回执行结果
5、Django把客户端想要的数据作为字符串返回客户端
6、客户端接收数据,再渲染到页面展现给用户
Django内置组件
admin,from,modelfrom,model
FBV和CBV
FBV:基于函数的视图函数
CBV:基于类的视图函数
session和cookie
区别:
cookie数据存放于客户的浏览器中,session的数据存于服务器中,cookie不是很安全,他人可以分析存放于本地的cookie并进行cookie欺骗,若从安全面考虑则应该使用session,session会在一定的时间内保存在服务器上。当访问量增多,会比较占用服务器的性能,所以建议将登陆信息等重要的信息存放在session中,其他信息则放在cookie中
HTTP请求常见的方式
1、opions 返回服务器针对特定资源所支持的HTML请求方法,允许客户端查看服务器性能
2、Get 向特定资源发出请求
3、post 向指定资源位置提交数据进行处理请求(提交表单,上传文件),又可能导致新的资源的建立或原有资源的修改
4、put 向指定资源位置上传最新内容
5、head
6、delete
7、trace
8、connect
MVC和MTV模式
Django的MTV模式本质上和MVC是一样的,也是为了各组件间保持松耦合关系,只是定义上有些许不同。
Django的MTV分别是指:
M 代表模型(Model): 负责业务对象和数据库的关系映(ORM)
T 代表模板 (Template):负责如何把页面展示给用户(html)
V 代表视图(View): 负责业务逻辑,并在适当时候调用Model和Template。
除了以上三层之外,还需要一个URL分发器,它的作用是将一个个URL的页面请求分发给不同的View处理,View再调用相应Model Template 优势:低耦合,开发快捷,部署方便,可重用性高,维护成本低。
ORM
对象关系映射
优点:ORM使得数据库的交互更加简单了,并且不用考虑开始的sql语句,实现快速开发
缺陷:sql封装死了 有时候查询速度很慢
中间件的4种方法及应用场景
自定义中间件必须继承MiddlewareMixin
from django.utils.deprecation import MiddlewareMixin
方法:
process_request
process_view
process_exception view中出现错误执行该方法
process_response
process_template_responseprocess 函数中有render执行
什么是wsgi、uwsgi、uWSGI
wsgi:
是web网关接口,是一套协议,用于接收用户请求并将请求进行初次封装,随即将请求交给web框架
实现wsgi协议的模块:
1、wsgiref:本质上就是编写一个socket服务端,用于接收用户请求(django)
2、werkzeug:本质上就是编写一个socket服务端,用于接收用户请求(flask)
uwsgi:
与wsgi一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
uWSGI:
是一个web服务器,实现了wsgi协议,uWSGI协议,http协议
ORM中的方法
1、model.表名.objects.all() 获取表中所有对象,结果是对象列表
2、model.表名.objects.get(条件) 获取符合条件的对象
3、model.表名.objects.filter(条件) 筛选所有符合条件的对象
4、model.表名.objects.exclude(条件) 筛选所有不合符条件的对象
5、model.表名.objects.all().values() 字典列表 values()括号内不指定则显示全部,若有指定则显示指定的
6、model.表名.objects.all().values_list() 元祖列表 括号内指定同上
7、model.表名.objects.all().order_by('id') 按照ID升序
8、model.表名.objects.all().order_by('-id') 按ID降序
9、model.表名.objects.all().order_by('a','-id') 先按a升序,a字段相同的按ID降序
10、model.表名.objects.all().order_by('-id').reverse() 对结果反转,reverse前必须排序,否则无效;或在model中表类下中的Meta中指定ordering=('id',) 注意逗号不能少
11、distinct() 去重
12、model.表名.objects.filter().exists() 判断列表是否有东西,返回true或false
ORM中三种能写sql语句的方法
1、execute 直接访问数据库,避开模型层
2、extra
3、raw for p in Person.objects.raw('SELECT * FROM myapp_person') print(p)
ORM批量处理数据
插入数据:
创建一个对象列表,然后调用bulk_create方法,一次性将列表中的数据插入数据库
product_list_to_insert = list()
for x in range(10):
product_list_to_insert.append(Product(name='product name' + str(x),price=x))
Product.objects.bulk_create(product_list_to_insert)
更新数据:先进行数据过滤,再调用update方法一次性更新
Product.objects.filter(name_contains='name').update(name='new name')
删除数据:先进行数据过滤,然后再调用delete方法删除
Product.objects.filter(name_contains='name query').delete()
CSRF实现机制
1、查看中间件是否启用,未启用则启动中间件
2、post请求
3、验证码
4、表单中添加{% csrf_token %}标签
Django中提供了runserver为什么不能用户来部署项目(runserver和uWSGI的区别)
1、runserver方法是调试Django时用到的运行方式,是Django自带的
WSGI server运行主要在测试和开发中使用,runserver开启的是单进程
2、uWSGI是一个web服务器,实现了wsgi协议,uWSGI协议,http协议,它具有超快的性能,低内存占用和多app管理等优点,与nginx搭配可构成一个生产环境,能够将用户访问请求和应用app隔开,实现真正的部署
calss Meta中原信息字段有哪些
1、app_label 应用场景:模型类不在默认的应用程序包下的models文件中,这时候需要指定你这个模型类是哪个应用程序的
2、db_table 应用场景:用于指定自定义数据库表名
3、db_tablespace 应用场景:通过该字段指定模型对应的数据库表放在哪个数据库表空间
4、verbose_name 应用场景:给模型类起名字,注释
5、verbose_name_plural 应用场景:模型的复数形式是什么
6、ordering 应用场景:对象返回的记录结果集是按哪个字段排序的
get和filter方法的区别
输入参数:
get的参数只能是model中定义的字段,只支持严格匹配
filter的参数可以使字段,也可以是扩展的where查询关键字,如in like
返回值:
get返回值是一个定义的model对象
filter返回值是一个新的queryset对象,然后可以对queryset再进行查询,再返回新的qureyset对象,支持链式操作,queryset是一个集合对象,支持迭代、遍历、切片等,但不同等于list
异常:
get只有一条记录返回的时候才正常,也就是说明get查询的字段必须是主键或唯一约束的字段,其余的都会抛异常
filter有没有匹配记录都不会抛异常
http请求的执行流程
1、域名解析
2、建立连接
3、接收请求 接收客户端访问某一资源的请求
单进程I/O 多进程I/O 复用I/O
4、处理请求
5、访问资源
6、构建响应报文
7、发送响应报文
8、记录日志
select_related和prefetch_related的区别
有外键关系存在时,可以很好的减少数据库的请求次数,减轻数据库的压力,提高性能
select_related通过表关系join关联查询,一次性获取所有数据,只进行一次sql查询
prefetch_related分别查询每一个表,根据之间的关系进行处理,执行两次sql查询
Django中orm如何设置读写分离
1、手动设置:通过using(db_name)来指定使用的数据库
2、自动读写分离:
1、定义类
2、配置settings文件,在其中指定DATEBASE
什么是RPC
定义:远程过程调用(RPC)是一种协议,程序可使用这种协议向网络中的另一台计算机上的程序请求服务
1、RPC采用客户机/服务器模式,请求程序就是一个客户机,而服务提供程序就是一个服务器
2、客户机调用进程发送一个有进程参数的调用信息到服务进程,等待应答。在服务端,进程保持睡眠状态直至调用信息到达,当第一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,继续等待下一个调用信息
3、客户端调用进程接收答复信息,获得进程结果,调用继续执行
如何实现用户的登陆认证
1、cookie session
2、token登陆成功后生成加密字符串
3、JWT就是一种用户在登录后生成token并把token存放于前端,后端不需要维护用户的状态信息但是可以进行验证token有效性的认证及状态管理方式
4、最后一步签名的过程其实是对头部以及负载的内容进行签名处理,防止内容被篡改,提高安全性
django rest framework框架中都有哪些组件
1、序列化组件:serializers 对queryset序列化以及对请求数据格式教研
2、认证组件:写一个类并注册到认证类 在类的方法中编写认证逻辑
3、权限组件:写一个类并注册到权限类 在类的方法中编写认证逻辑
4、频率组件:写一个类并注册到频率类 在类的方法中编写认证逻辑
5、渲染器:定义数据如何渲染至页面,在渲染器类中注册
6、分页:对获取到的数据进行分页处理
1、基本分页:pagenumberpagination
2、偏移分页:limitoffsetpagination
3、游标分页:Cursorpagination
使用orm和原生sql的优缺点
1、orm的开发速度快,操作简单,但是执行速度较慢,在处理多表联查等复杂操作时orm语法会变得复杂
2、sql开发速度慢,但是执行速度快,性能强
F、Q查询
F作用:两个字段之间做比较,专门取对象中某列值的操作
Q作用:对对象进行复杂查询,支持特殊操作符运算来组合生成不同的Q对象
你能列举几个减少数据库查询次数的方法吗
1、利用Django queryset的惰性和自带缓存的特性
2、使用select_related和prefetch_related方法在数据库层面进行Join操作
3、使用缓存
Django的模型继承有哪几种方式? 它们有什么区别以及何时使用它们?
1. 抽象模型继承(abstract model)
2. 多表模型继承(multi-table inheritance)
3. 代理模型(proxy model)
它们的区别如下:
1、Django不会为抽象模型在数据库中生成自己的数据表。父类Meta中的abstract=True也不会传递给子类。如果你发现多模型有很多共同字段时,需使用抽象模型继承。
2、多表模型继承与抽象模型继承最大的区别在于Django也会为父类模型建立自己的数据表,同时隐式地在父类和子类之间建立一个一对一关系。
3、如果我们只想改变某个模型的行为方法,而不是添加额外的字段或创建额外的数据表,我们就可以使用代理模型(proxy model)。设置一个代理模型,需要在子类模型Meta选项中设置proxy=True, Django不会为代理模型生成新的数据表