总结的一些Django中会问的问题,希望对你们有用。
1、 Django的生命周期
当用户在浏览器输入url时,浏览器会生成请求头和请求体发送给服务端,url经过Django中的wsgi时请求对象创建完成,经过django的中间件,然后到路由系统匹配路由,匹配成功后走到相对应的views函数,视图函数执行相关的逻辑代码返回执行结果,Django把客户端想要的数据作为一个字符串返回给客户端,客户端接收数据,渲染到页面展现给用户
2、 内置组件
Admin、from、modelfrom、model
3、 缓存方案
设置缓存到内存
缓存到redis,配置redis
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://39.96.61.39:6379",
'PASSWORD':'19990104.Yu',
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}
单个view缓存
视图导入from django.views.decorators.cache import cache_page
在需要进行缓存的视图函数上添加如下装饰器即可:
@cache_page(60 * 2)#20分钟
底层缓存API
视图导入 from django.core.cache import cache
模板片段缓存
使用cache标签进行缓存
在HTML文件中添加:
{%load cache%}
{%cache 60 缓存名字 %}
4、 FBV和CBV
FBV:基于函数的视图函数
CBV:基于类的视图函数
5、 session和cookie
区别:
cookie数据存放在客户的浏览器上,session数据放在服务器上
cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗
考虑到安全应当使用session。
session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用COOKIE
单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie
建议:将登陆信息等重要信息存放为SESSION,其他信息如果需要保留,可以放在COOKIE中
Cookie代码
HttpCookie cookie = new HttpCookie("MyCook");//初使化并设置Cookie的名称
DateTime dt = DateTime.Now;
TimeSpan ts = new TimeSpan(0, 0, 1, 0, 0);//过期时间为1分钟
cookie.Expires = dt.Add(ts);//设置过期时间
cookie.Values.Add("userid", "value");
cookie.Values.Add("userid2", "value2");
Response.AppendCookie(cookie);
6、 HTTP请求常见的方式
1、opions 返回服务器针对特定资源所支持的HTML请求方法 或web服务器发送测试服务器功能(允许客户端查看服务器性能)
2、Get 向特定资源发出请求(请求指定页面信息,并返回实体主体)
3、Post 向指定资源提交数据进行处理请求(提交表单、上传文件),又可能导致新的资源的建立或原有资源的修改
4、Put 向指定资源位置上上传其最新内容(从客户端向服务器传送的数据取代指定文档的内容)
5、Head 与服务器索与get请求一致的相应,响应体不会返回,获取包含在小消息头中的原信息(与get请求类似,返回的响应中没有具体内容,用于获取报头)
6、Delete 请求服务器删除request-URL所标示的资源(请求服务器删除页面)
7、Trace 回显服务器收到的请求,用于测试和诊断
8、Connect HTTP/1.1协议中能够将连接改为管道方式的代理服务器
7、 MVC和MTV模式
MTV:Model(模型):负责业务对象与数据库的对象(ORM)
Template(模版):负责如何把页面展示给用户
View(视图):负责业务逻辑,并在适当的时候调用Model和Template
MVC: 所谓MVC就是把web应用分为模型(M),控制器(C),视图(V)三层;他们之间以一种插件似的,松耦合的方式连接在一起。模型负责业务对象与数据库的对象(ORM),视图负责与用户的交互(页面),控制器(C)接受用户的输入调用模型和视图完成用户的请求。
8、 ORM
对象关系映射
优点:
1、ORM使得我们的通用数据库交互变得简单易行,并且完全不用考虑开始的SQL语句。快速开发,由此而来。
2、可以避免一些新手程序猿写sql语句带来的性能效率和安全问题。
缺点:
1、性能有所牺牲,不过现在的各种ORM框架都在尝试使用各种方法来减少这个问题(LazyLoad,Cache),效果还是很显著的。
2、对于个别的负责查询,ORM仍然力不从心。为了解决这个问题,ORm框架一般也提供了直接写原生sql的方式。
9、 中间件的作用
中间件是介于request与response处理之间的一道处理过程,能在全局上改变django的输入与输出
10、 中间件的4种方法及应用场景(自定义中间件必须继承MiddlewareMixin)
导包、from django.utils.deprecation import MiddlewareMixin
4种方法:
process_request
process_view
process_exception views中出现错误执行该方法
process_response
process_template_responseprocess 当函数中有render方法会执行该方法
11、什么是wsgi,uwsgi,uWSGI?
WSGI:
web服务器网关接口,是一套协议。用于接收用户请求并将请求进行初次封装,然后将请求交给web框架
实现wsgi协议的模块:
1.wsgiref,本质上就是编写一个socket服务端,用于接收用户请求(django)
2.werkzeug,本质上就是编写一个socket服务端,用于接收用户请求(flask)
uwsgi:
与WSGI一样是一种通信协议,它是uWSGI服务器的独占协议,用于定义传输信息的类型
uWSGI:
是一个web服务器,实现了WSGI协议,uWSGI协议,http协议
12、ORM中的方法
1. models.Book.objects.all() # 获取到所有的书籍对象,结果是对象列表
2. models.Book.objects.get(条件) # 获取符合条件的对象
3. models.Book.objects.filter(条件) # 筛选所有符合条件的,结果是对象列表
4. models.Book.objects.exclude(条件) # 筛选出所有不符合条件的,结果是对象列表
5. models.Book.objects.all().values( ) # 字典列表,[ {id:1,name:20} , {id:2,name:18} ]
values(‘id’)括号内不指定时显示全部,如指定则只显示指定的,[ {id:1} , {id:2,} ]
6. models.Book.objects.all().values_list( ) # 元组列表,[ (1,20) , (2,18) ]同上,指定时显示指定内容
7. models.Book.objects.all().order_by(‘id’) # 按照id升序就行排列
models.Book.objects.all().order_by(‘-id’) # 按照id降序就行排列
models.Book.objects.all().order_by(‘age’ , ‘-id’) # 先按age升序,age相同的按id进行降序排列
8. models.Book.objects.all().order_by(‘id’).reverse() # 对结果反转; 注意reverse前必须排序,
否则reverse无效; 或在model.py文件中Book类中的Meta中指定ordering=(‘id’ , )注意逗号必须有
9. distinct(): # 去重,当获取到的结果Queryset列表中同一对象出现多次时去重,只留一个
10. models.Book.objects.all().count() # 计数,可统计结果个数,如对Queryset内元素数进行统计.
11. models.Book.objects.all().first() # 获取结果中的第一条,即使前面结果列表为空,也不会报错
12. models.Book.objects.filter().last() # 获取结果中的最后一条
13.models.Book.objects.filter().exists() # 判断Queryset列表是否有东西,结果为True或False;
返回对象列表(Queryset)的方法有:
all() filter() ordey_by() exclude() values() values_list() reverse() distinct()
返回单个对象的方法有:
first() last() get() create()创建一个对象,且返回刚创建的对象
判断布尔值的有:
exists()
返回数字的有:
count()
13、filter和exclude的区别
filter返回满足条件的数据
exclude返回不满足条件的数据
14、ORM中三种能写sql语句的方法
1、execute 直接访问数据库,避开模型层
2、extra
3、raw for p in Person.objects.raw('SELECT * FROM myapp_person'):
print(p)
15、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()
16、CSRF实现机制
1)启用中间件
2)post请求
3)验证码
4)表单中添加{% csrf_token%}标签
17、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 隔离开,实现真正的署 。
相比来讲,支持的并发量更高,方便管理多进程,发挥多核的优势,提升性能。
18、Django中如何实现websocket
1、简述:django实现websocket,之前django-websocket退出到3.0之后,被废弃。官方推荐大家使用channels。
2、配置
1、需要在seting.py里配置,将我们的channels加入INSTALLED_APP里。
19、Django的跨域问题
1、为什么有跨域?
1、浏览器的同源策略 (从一个域上加载的脚本不允许访问另外一个域的文档属性。)
2、解决跨域问题
1、前端设置代理进行访问
2、settings中配置django-cors-headers==2.0.1
INSTALLED_APPS中添加 ‘corsheaders’
'corsheaders.middleware.CorsMiddleware',#放在session中间件下面
添加代码
CORS_ALLOW_CREDENTIALS = True
CORS_ORIGIN_ALLOW_ALL = True
#允许所有的请求头
CORS_ALLOW_HEADERS = ('*')
20、model继承有几种方式,分别是什么?
抽象基类(Abstract base classes)
多表继承(Multi-table inheritance)
Meta inheritance 当一个子类没有声明自己的Meta类时,它会继承基类的 Meta 类,如果子类想扩展基类的 Meta 类 ,它可以继承基类的Meta类,然后再进行扩展。
21、values和values_list()的区别
values : 取字典的queryset
values_list : 取元组的queryset
22、class Meta中的原信息字段有哪些?
1、app_label 应用场景:模型类不在默认的应用程序包下的models.py文件中,这时候你需要指定你这个模型类是那个应用程序的。
2、db_table 应用场景:用于指定自定义数据库表名的
3、db_tablespace 应用场景:通过db_tablespace来指定这个模型对应的数据库表放在哪个数据库表空间。
4、verbose_name 应用场景:给你的模型类起一个更可读的名字:
5、verbose_name_plural 应用场景: 模型的复数形式是什么
6、ordering 应用场景:象返回的记录结果集是按照哪个字段排序的
23、视图函数中,常用的验证装饰器有哪些?
24、web框架的本质
socket服务端
自定制web框架
from wsgiref.simple_server import make_server
def index():
return b'index'
def login():
return b'login'
def routers():
urlpatterns = (
('/index/', index),
('/login/', login),
)
return urlpatterns
def RunServer(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/html')])
url = environ['PATH_INFO']
urlpatterns = routers()
func = None
for item in urlpatterns:
if item[0] == url:
func = item[1]
break
if func:
return [func()]
else:
return [b'404 not found']
if __name__ == '__main__':
httpd = make_server('127.0.0.1',8080,RunServer)
print("Serving HTTP on port 8080...")
httpd.serve_forever()
25、queryset的get和filter方法的区别
输入参数:
get的参数只能是model中定义的那些字段,只支持严格匹配
filter的参数可以是字段,也可以是扩展的where查询关键字,如in,like等
返回值:
get返回值是一个定义的model对象
filter返回值是一个新的QuerySet对象,然后可以对QuerySet在进行查询返回新的QuerySet对象,支持链式操作。QuerySet一个集合对象,可使用迭代或者遍历,切片等,但是不等于list类型
异常:
get只有一条记录返回的时候才正常,也就说明get的查询字段必须是主键或者唯一约束的字段。当返回多条记录或者是没有找到记录的时候都会抛出异常。
filter有没有匹配记录都可以。
26、http请求的执行流程
1、域名解析
2、建立连接
3、接收请求 接收客户端访问某一资源的请求
单进程I/O
多进程I/O
复用I/O
4、处理请求
5、访问资源
6、构建响应报文
7、发送响应报文
8、记录日志
27、如何加载初始化数据
Body中写onload方法
Js代码写onload函数执行的过程
28、对Django的认知
#1.Django是走大而全的方向,它最出名的是其全自动化的管理后台:只需要使用起ORM,做简单的对象定义,它就能自动生成数据库结构、以及全功能的管理后台。
#2.Django内置的ORM跟框架内的其他模块耦合程度高。
#应用程序必须使用Django内置的ORM,否则就不能享受到框架内提供的种种基于其ORM的便利;
#理论上可以切换掉其ORM模块,但这就相当于要把装修完毕的房子拆除重新装修,倒不如一开始就去毛胚房做全新的装修。
#3.Django的卖点是超高的开发效率,其性能扩展有限;采用Django的项目,在流量达到一定规模后,都需要对其进行重构,才能满足性能的要求。
#4.Django适用的是中小型的网站,或者是作为大型网站快速实现产品雏形的工具。
#5.Django模板的设计哲学是彻底的将代码、样式分离; Django从根本上杜绝在模板中进行编码、处理数据的可能。
2. Django 、Flask、Tornado的对比
#1.Django走的是大而全的方向,开发效率高。它的MTV框架,自带的ORM,admin后台管理,自带的sqlite数据库和开发测试用的服务器
#给开发者提高了超高的开发效率
#2.Flask是轻量级的框架,*,灵活,可扩展性很强,核心基于Werkzeug WSGI工具和jinja2模板引擎
#3.Tornado走的是少而精的方向,性能优越。它最出名的是异步非阻塞的设计方式
#Tornado的两大核心模块:
#1.iostraem:对非阻塞式的socket进行简单的封装
#2.ioloop:对I/O多路复用的封装,它实现了一个单例
29、重定向的实现,用的状态码
1.使用HttpResponseRedirect
from django.http import HttpResponseRedirect
2.使用redirect和reverse
状态码:301和302 #301和302的区别:
相同点:都表示重定向,浏览器在拿到服务器返回的这个状态码后会自动跳转到一个新的URL地址
不同点: 301比较常用的场景是使用域名跳转。
30、nginx的正向代理与反向代理
正向代理:多台客户端访问远程资源的时候通过的是代理服务器,例如(FQ)
反向代理:多台客户端访问服务器上的资源的时候,如果用户数量超过了服务器的最大承受限度,通过反向代理分流,把多台客户访问的请求分发到不同的服务器上解决服务器压力的问题
31、路由系统中name的作用
用于反向解析路由,相当于给url取个别名,只要这个名字不变,即使对应的url改变 通过该名字也能找到该条url
32、select_related和prefetch_related的区别?
有外键存在时,可以很好的减少数据库请求的次数,提高性能
#select_related通过多表join关联查询,一次性获得所有数据,只执行一次SQL查询
#prefetch_related分别查询每个表,然后根据它们之间的关系进行处理,执行两次查询
33、django orm 中如何设置读写分离?
1.手动读写分离:通过.using(db_name)来指定要使用的数据库
2.自动读写分离:
1.定义类:如Router #
2.配置Router settings.py中指定DATABASE_ROUTERS
DATABASE_ROUTERS = ['myrouter.Router',]
34、django中如何根据数据库表生成model中的类?
1.在settings中设置要连接的数据库
2.生成model模型文件
python manage.py inspectdb
3.模型文件导入到models中
python manage.py inspectdb > app/models.py
35、什么是RPC
远程过程调用 (RPC) 是一种协议,程序可使用这种协议向网络中的另一台计算机上的程序请求服务
1.RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。
2.首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。 2.在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,
3.最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。
36、如何实现用户的登录认证
1.cookie session
2.token 登陆成功后生成加密字符串
3.JWT:json wed token缩写 它将用户信息加密到token中,服务器不保存任何用户信息 #服务器通过使用保存的密钥来验证token的正确性
37、抽象继承
38、is_valid()的用法
检查对象变量是否已经实例化即实例变量的值是否是个有效的对象句柄
39、取消级联删除
40、pv和uv
1.pv:页面访问量,没打开一次页面PV计算+1,页面刷新也是
#2.UV:独立访问数,一台电脑终端为一个访客
41、django rest framework框架中都有那些组件?
1.序列化组件:serializers 对queryset序列化以及对请求数据格式校验
2.认证组件 写一个类并注册到认证类(authentication_classes),在类的的authticate方法中编写认证逻
3.权限组件 写一个类并注册到权限类(permission_classes),在类的的has_permission方法中编写认证逻辑
4.频率限制 写一个类并注册到频率类(throttle_classes),在类的的allow_request/wait 方法中编写认证逻辑
5.渲染器 定义数据如何渲染到到页面上,在渲染器类中注册(renderer_classes)
6.分页 对获取到的数据进行分页处理, pagination_class
42、使用orm和原生sql的优缺点?
1.orm的开发速度快,操作简单。使开发更加对象化 #执行速度慢。处理多表联查等复杂操作时,ORM的语法会变得复杂
2.sql开发速度慢,执行速度快。性能强
43、F和Q的作用?
F:对数据本身的不同字段进行操作 如:比较和更新
Q:用于构造复杂的查询条件 如:& |操作