Django知识总结

1 django中间件使用?

 

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

但是由于其影响的是全局,所以需要谨慎使用,使用不当会影响性能。

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

中间件可以定义五个方法,分别是:(主要的是process_request和process_response)

  • process_request(self,request)  是在执行视图函数之前执行的。
  • process_view(self, request, view_func, view_args, view_kwargs) 是在process_request之后,视图函数之前执行的
  • process_template_response(self,request,response) 是在视图函数执行完成后立即执行,但是它有一个前提条件,那就是视图函数返回的对象有一个render()方法(或者表明该对象是一个TemplateResponse对象或等价方法)
  • process_exception(self, request, exception) 只有在视图函数中出现异常了才执行
  • process_response(self, request, response) 是在视图函数之后执行的

以上方法的返回值可以是None或一个HttpResponse对象,如果是None,则继续按照django定义的规则向后继续执行,如果是HttpResponse对象,则直接将该对象返回给用户。

当配置多个中间件时,会按照MIDDLEWARE中的注册顺序,也就是列表的索引值,从前到后依次执行的。

不同中间件之间传递的request都是同一个对象

2 django请求的生命周期?

 

在Django中,当我们访问一个的url时,会通过路由匹配进入相应的html网页中.

Django的请求生命周期是指当用户在浏览器上输入url到用户看到网页的这个时间段内,Django后台所发生的事情

而Django的生命周期内到底发生了什么呢?

1. 当用户在浏览器中输入url时,浏览器会生成请求头和请求体发给服务端 请求头和请求体中会包含浏览器的动作(action),这个动作通常为get或者post,体现在url之中.

2. url经过Django中的wsgi,再经过Django的中间件,最后url到过路由映射表,在路由中一条一条进行匹配, 一旦其中一条匹配成功就执行对应的视图函数,后面的路由就不再继续匹配了.

3. 视图函数根据客户端的请求查询相应的数据.返回给Django,然后Django把客户端想要的数据做为一个字符串返回给客户端.

4. 客户端浏览器接收到返回的数据,经过渲染后显示给用户.

3 FBV模式和CBV模式

一个url对应一个视图函数,这个模式叫做FBV(Function Base Views)

除了FBV之处,Django中还有另外一种模式叫做CBV(Class Base views),即一个url对应一个类

例子:使用cbv模式来请求网页

路由信息:

urlpatterns = [
	url(r'^fbv/',views.fbv),
	url(r'^cbv/',views.CBV.as_view()),
]

使用fbv的模式,在url匹配成功之后,会直接执行对应的视图函数.

而如果使用cbv模式,在url匹配成功之后,会找到视图函数中对应的类,然后这个类回到请求头中找到对应的请求方式

 4 浅谈uWSGI和Nginx?

WSGI 没有官方的实现, 因为WSGI更像一个协议. 只要遵照这些协议,WSGI应用(Application)都可以在任何服务器(Server)上运行, 反之亦然。
WSGI标准在 PEP 333 中定义并被许多框架实现,其中包括现广泛使用的django框架

uWSGI是一种web服务器,它实现了WSGI协议,uwsgi,http等协议。nginx中HttpUwsgiModel的作用是与uWSGI服务器进行交互,WSGI是一种web服务器的网关接口,它是web服务器通信的一种规范

注意uWSGI,uwsgi,WSGI三个概念区分

uwsgi是一种线路协议而不是通信协议,在此用于uWSGI服务器与其他网络服务器的数据通信

uWSGI是实现了uwsgi和WSGI两种协议的web服务器

nginx是一个开源的高性能的http服务器

1 作为web服务器它处理静态文件和索引文件效率非常高

2 它的设计非常注重效率。最高支持5万个并发连接,但只占用很少的内存空间

3 稳定性高,配置简洁

4 强大的反向代理和负载均衡功能,平衡集群中各个服务器的负载压力

反向代理:

反向代理,其实客户端对代理是无感知的,因为客户端不需要任何配置就可以访问,我们只需要将请求发送到反向代理服务器,由反向代理服务器去选择目标服务器获取数据后,在返回给客户端,此时反向代理服务器和目标服务器对外就是一个服务器,暴露的是代理服务器地址,隐藏了真实服务器IP地址。

正向代理:

举一个例子:大家都知道,现在国内是访问不了 Google的,那么怎么才能访问 Google呢?我们又想,美国人不是能访问 Google吗(这不废话,Google就是美国的),如果我们电脑的对外公网 IP 地址能变成美国的 IP 地址,那不就可以访问 Google了。你很聪明,VPN 就是这样产生的。我们在访问 Google 时,先连上 VPN 服务器将我们的 IP 地址变成美国的 IP 地址,然后就可以顺利的访问了。

  这里的 VPN 就是做正向代理的。正向代理服务器位于客户端和服务器之间,为了向服务器获取数据,客户端要向代理服务器发送一个请求,并指定目标服务器,代理服务器将目标服务器返回的数据转交给客户端。这里客户端是要进行一些正向代理的设置的。

PS:这里介绍一下什么是 VPN,VPN 通俗的讲就是一种中转服务,当我们电脑接入 VPN 后,我们对外 IP 地址就会变成 VPN 服务器的 公网 IP,我们请求或接受任何数据都会通过这个VPN 服务器然后传入到我们本机。这样做有什么好处呢?比如 VPN 游戏加速方面的原理,我们要玩网通区的 LOL,但是本机接入的是电信的宽带,玩网通区的会比较卡,这时候就利用 VPN 将电信网络变为网通网络,然后在玩网通区的LOL就不会卡了(注意:VPN 是不能增加带宽的,不要以为不卡了是因为网速提升了)。

正向代理代理客户端,反向代理代理服务器。

5 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 服务的一个 理想框架。

6 Celery原理?

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAaHVjaGFvc2hhbg==,size_20,color_FFFFFF,t_70,g_se,x_16

celery由任务队列broker和任务处理者worker组成,客户端发送任务到broker,worker通过不断监听任务队列,从中获取新的任务进行处理,celery是异步的,任务队列一般使用数据库rabbitMQ进行存储,也可以使用redis,使用redis就是无法避免因意外中断或电源故障导致数据丢失的情况。 

7 常见状态码?

  • 200("OK")
    一切正常。实体主体中的文档(若存在的话)是某资源的表示。

  • 400("Bad Request")
    客户端方面的问题。实体主题中的文档(若存在的话)是一个错误消息。希望客户端能够理解此错误消息,并改正问题。

  • 500("Internal Server Error")
    服务期方面的问题。实体主体中的文档(如果存在的话)是一个错误消息。该错误消息通常无济于事,因为客户端无法修复服务器方面的问题。

  • 301("Moved Permanently")
    当客户端触发的动作引起了资源URI的变化时发送此响应代码。另外,当客户端向一个资源的旧URI发送请求时,也发送此响应代码。

  • 404("Not Found") 和410("Gone")
    当客户端所请求的URI不对应于任何资源时,发送此响应代码。404用于服务器端不知道客户端要请求哪个资源的情况;410用于服务器端知道客户端所请求的资源曾经存在,但现在已经不存在了的情况。

  • 409("Conflict")
    当客户端试图执行一个”会导致一个或多个资源处于不一致状态“的操作时,发送此响应代码。

8 django中如何在model保存前做一定的固定操作,比如写一段日志? 

利用django的信号管理机制

django.db.models.signals.pre_save()方法可实现

pre_init()当模型实例化时调用,在init()之前执行

pre_save()在model执行save方法前被调用

pre_delete()在执行Model的delete()或者queryset的delete()方法前被调用

post_init()作用与模型实例化。在init之后被调用

post_save()在model执行save方法后被调用

post_delete()在model执行delete方法后被调用

m2m_changed()当Model的manytomanyfield发生改变时被调用

Signals.connect(receive, send=None, weak=True, dispath_uid=None)方法注册一个接收器函数,当信号被发送时接收器函数被调用

receive:连接到此信号的回调函数

send:指定要接受信号的特定发送方

weak:弱引用,为了防止被垃圾回收机制回收掉,一般传递weak=False

dispath_uid:给信号接收方定义一个唯一标识,防止肯能会重复信号发送

9 加密和解密?

加密算法分类

对称加密算法:

对称加密采用了对称密码编码技术,它的特点是文件加密和解密使用相同的密钥
发送方和接收方需要持有同一把密钥,发送消息和接收消息均使用该密钥。
相对于非对称加密,对称加密具有更高的加解密速度,但双方都需要事先知道密钥,密钥在传输过程中可能会被窃取,因此安全性没有非对称加密高。
常见的对称加密算法:DES,AES,3DES等等

非对称加密算法:

文件加密需要公开密钥(publickey)和私有密钥(privatekey)。
接收方在发送消息前需要事先生成公钥和私钥,然后将公钥发送给发送方。发送放收到公钥后,将待发送数据用公钥加密,发送给接收方。接收到收到数据后,用私钥解密。
在这个过程中,公钥负责加密,私钥负责解密,数据在传输过程中即使被截获,攻击者由于没有私钥,因此也无法破解。
非对称加密算法的加解密速度低于对称加密算法,但是安全性更高。
非对称加密算法:RSA、DSA、ECC等算法

消息摘要算法:

消息摘要算法可以验证信息是否被篡改。
在数据发送前,首先使用消息摘要算法生成该数据的签名,然后签名和数据一同发送给接收者。
接收者收到数据后,对收到的数据采用消息摘要算法获得签名,最后比较签名是否一致,以此来判断数据在传输过程中是否发生修改。

base64

s1 = base64.encodestring('hello world')
s2 = base64.decodestring(s1)

6bdc6a6272231db3c15c225b26814aeb.png

        优点:方法简单

        缺点:不保险,别人拿到密文可以自己解密出明文

MD5

3b4b820244746d546c490a5f70841a37.png

 特点:1不可逆的  2输入长度不定,输出长度一定(加密后长度一定)

Django自带的加密算法及加密模块

from django.contrib.auth.hashers import make_password, check_password

ps = "123456"

dj_ps = make_password(ps, None, 'pbkdf2_sha256')   #创建django密码, 第二个参数为None是每次产生的密码都不用,第三个参数为算法, 后面两个参数可以忽略

ps_bool = check_password(ps, dj_ps) # check_password 返回值为一个Bool类型,验证密码的正确与否

sha256

import hashlib
data = "你好"   # 要进行加密的数据
data_sha = hashlib.sha256(data.encode('utf-8')).hexdigest()   
print(data_sha)

10 RPC是什么意思?

RPC(Remote Procedure Call Protocol)—— 远程过程调用 协议, 它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议 。 RPC协议 假定某些 传输协议 的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI 网络通信 模型中,RPC跨越了 传输层 和 应用层 。RPC使得开发包括网络 分布式 多程序在内的应用程序更加容易。

RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复 信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果,然后调用执行继续进行。

工作原理(以Windows操作系统为例):

运行时,一次客户机对服务器的RPC调用,其内部操作大致有如下十步:

1.调用客户端句柄;执行传送参数

2.调用本地系统 内核发送网络消息

3. 消息传送到远程 主机

4.服务器句柄得到消息并取得参数

5.执行远程过程

5abba7691a13c66bcfb78ef07774c3a4.png

6.执行的过程将结果返回服务器句柄

7.服务器句柄返回结果,调用远程系统 内核

8.消息传回 本地主机

9.客户句柄由内核接收消息

10.客户接收句柄返回的数据

 

fd9facabcbc7f6f7cf967b80b0db6436.png

通过上面的图可以看出来,在RPC框架中主要有以下4个角色:

  • registry - 注册中心,当服务提供者启动时会向注册中心注册,然后注册中心会告知所有的消费者有新的服务提供者。
  • provider - 服务提供者,远程调用过程中的被消费方。
  • consumer - 服务消费者,远程调用过程中的消费方。
  • monitor - 监视器,它主要负责统计服务的消费和调用情况。

启动服务提供者后,服务提供者会以异步的方式向注册中心注册。然后启动服务消费者,它会订阅注册中心中服务提供者列表,当有服务提供者的信息发生改变时,注册中心会通知所有的消费者。当消费者发起远程调用时,会通过动态代理将需要请求的参数以及方法签名等信息通过Netty发送给服务提供者,服务提供者收到调用的信息后调用对应的方法并将产生的结果返回给消费者,这样就完成了一个完整的远程调用。当然了这个过程中可能还会将调用信息异步发送给monitor用于监控和统计。

11 django中ORM?

对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。

简单的说,ORM是通过使用描述对象和数据库之间映射的元数据,将程序中的对象自动持久化到关系数据库中。

ORM在业务逻辑层和数据库层之间充当了桥梁的作用。

ORM的优势#

ORM解决的主要问题是对象和关系的映射。它通常把一个类和一个表一一对应,类的每个实例对应表中的一条记录,类的每个属性对应表中的每个字段。 

ORM提供了对数据库的映射,不用直接编写SQL代码,只需像操作对象一样从数据库操作数据。

让软件开发人员专注于业务逻辑的处理,提高了开发效率。

watermark,type_d3F5LXplbmhlaQ,shadow_50,text_Q1NETiBAaHVjaGFvc2hhbg==,size_18,color_FFFFFF,t_70,g_se,x_16

 查询 API    Model.objects.filter()   Model.objects.get()

 <1> all():                  查询所有结果
  
<2> filter(**kwargs):       它包含了与所给筛选条件相匹配的对象
  
<3> get(**kwargs):          返回与所给筛选条件相匹配的对象,返回结果有且只有一个,如果符合筛选条件的对象超过一个或者没有都会抛出错误。
  
<4> exclude(**kwargs):      它包含了与所给筛选条件不匹配的对象
 
<5> order_by(*field):       对查询结果排序('-id')
  
<6> reverse():              对查询结果反向排序
  
<8> count():                返回数据库中匹配查询(QuerySet)的对象数量。
  
<9> first():                返回第一条记录
  
<10> last():                返回最后一条记录
  
<11> exists():              如果QuerySet包含数据,就返回True,否则返回False
 
<12> values(*field):        返回一个ValueQuerySet——一个特殊的QuerySet,运行后得到的并不是一系列
                            model的实例化对象,而是一个可迭代的字典序列
<13> values_list(*field):   它与values()非常相似,它返回的是一个元组序列,values返回的是一个字典序列
 
<14> distinct():            从返回结果中剔除重复纪录

 

12 django  执行原生SQL方法

 raw方式

models.表名.objecs.raw(sql)

models.表名.objecs.raw(sql,[参数1,参数2])

47af23cb90e4a59c34c7940232f5853c.png

 注:如果没有参数,就只写sql语句,如果由参数,后面需要用列表,如图所示

上述的,其实还是和django的model有些绑定。但是我就是说,我就是想要原生sql,不要跟任何绑定。

这里说一下,千万不要在django使用pymysql执行原生sql,会发生一些奇怪的问题。一定要导入from django.db import connection执行sql。代码如下:

from django.db import connection

def book_list(request):

    # 真正的原生sql,

    cursor = connection.cursor()

    print(type(cursor))

    cursor.execute("select * from app01_book where id=%s", [1, ])

    raw = cursor.fetchall()

    print(raw)

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值