40.django中重要概念

模板引擎

1.基本数据类型

  • 字符串、整数、小数
  • 列表
  • 字典
  • 列表套字典

2.母版

  • 母版页面(layout.html)

    {% block mycontent%}
    {% endblock %}
    
    {% block mycss%}
    {% endblock %}
    
    {% block myjs%}
    {% endblock %}
    
  • 子版页面

    {%extends "layout.html"%} 继承母版
    
    {% block mycontent%}
     子版自己的内容
    {% endblock %}
    

3.导入模块方式

使用include: {% include " xxx.html" %} 可以导入对应模板中的内容

4.内置函数

str='cc FF gg AA'

html模板中:
{{ str|upper }}     CC FF GG AA
{{ str|lower }}       cc ff gg aa
{{ str|first|upper }}   c
{{ str|truncatewords:"3" }}  cc FF gg...

5.自定义函数

a. 在app中创建templatetags目录
b. 在上述的目录中创建 xxx.py
c. 在xxx.py中,
from django import template

register = template.Library()

@register.filter
def my_filter(val, args):
	return val + args

@register.simple_tag
def my_upper(val, args, args1):
	return val + args + args1


在html中:
{%load xxx %}

- simple_filter
{{name | my_filter:'xxxxx'}}

- simple_tag
{%my_upper "zekai" "sss" 'dsadsadsa'%}

不建议在模板中使用函数, 因为会降低模板的渲染效率, 建议在视图函数中直接处理, 然后渲染即可

cookie,session

cookie是存在于客户端的,   
   它的作用是:
       验证登录信息的,通过使用 cookie完善登录的逻辑

   为了便于理解可以把cookie当作记录了登录信息的小纸条,并且有一定的生效时间。
   cookie具体在网络中的机制是:
   1.首先浏览器客户端登录访问服务端时,服务端提供登录页面给浏览器
   2.浏览器端提交数据给服务器,相当于记录信息(是session的机制)
   3.此时服务端会回写cookie给浏览器,也就是相当于递了一个小纸条给浏览器
   4.浏览器将cookie保存,并发送第二次请求,而且要带上cookie
   5.服务端通过认证,可以请求其他数据。
      
   在python中具体的用法是:
 通过set_cookie这个函数,后面跟的参数有,key-value,
  是cookie的键值对,用来设定值,通过判断来确定是否需要登录,
  后面有一个参数是max_age,表示登录后生效的时间,超过此时间,     	  cookie会被清除,则需要再次登录。
  
  还有expires也是表示生效时间,以年月日形式,最少设为一天
  domain是表示生效的域名
  
  如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的	
  
  我们可以通过document.cookie打出cookie的内容
  只要通过设置HttpOnly=true,这样cookie就不能被js获取到    
       
  为了安全性:我们还可以加盐处理set_signed_cookie(key, val,  salt)
session在服务端,依赖于cookie的,用来登记信息

session机制:
1. 向客户端回写一个 {sessionid : 'lr3gmj3vpt0ytf7locqnb21p0cg63iek'}的cookie值
2. 将客户的隐私信息保存在了服务端的数据库中,也就是session保存在了数据库中
默认放在django_session表中
{"dsjnalndjskanjdksa" : {"name":'xxx', 'age':18, 'addr':'dsabdsa'}}

#### 在视图函数中设置session的方法:
request.session['name'] = username
request.session['age'] = 13

#### 获取session
request.session.get('name')

### 默认session存在数据库中的django_session表

#还可以通过缓存,文件或者缓存加数据库的方式保存session

中间件

在django中,浏览器和服务端之间发送请求和响应时需要通过中间件,在django的settings中,有一个 MIDDLEWARE_列表中,每一个元素就是一个中间件。

当django处理一个 Request 的过程是首先通过中间件,然后再通过默认的 URL 方式进行的。我们可以在 Middleware 这个地方把所有Request 拦截住,用我们自己的方式完成处理以后直接返回 Response。

中间件定义方法

中间件中可以定义五个方法,具体如下:

Request预处理函数: process_request(self, request)

这个方法的调用时机在Django接收到request之后,但仍未解析URL以确定应当运行的视图函数。Django向它传入相应的Request对象,以便在方法中修改。

如果返回None,Django将继续处理这个request,执行后续的中间件, 然后调用相应的 view。

如果返回HttpResponse对象,Django将不再执行任何除了process_response以外其它的中间件以及相应的view,Django将立即返回该HttpResponse。

View预处理函数: process_view(self, request, callback, callback_args,callback_kwargs)

这个方法的调用时机在 Django 执行完 request 预处理函数并确定待执行的 view (即callback参数)之后,但在 view 函数实际执行之前。

request:HttpRequest 对象。

callback:Django将调用的处理request的python函数. 这是实际的函数对象本身, 而不是字符串表述的函数名。

args:将传入view的位置参数列表,但不包括request参数(它通常是传入view的第一个参数)。

kwargs:将传入view的关键字参数字典。

process_view() 应当返回None或 HttpResponse 对象。如果返回 None, Django将继续处理这个request ,执行后续的中间件, 然后调用相应的view。

如果返回 HttpResponse 对象,Django 将不再执行任何其它的中间件(不论种类)以及相应的view,Django将立即返回。

Template模版渲染函数:process_template_response()

默认不执行,只有在视图函数的返回结果对象中有render方法才会执行,并把对象的render方法的返回值返回给用户(注意不返回视图函数的return的结果了,而是返回视图函数 return值(对象)中rende方法的结果)

Exception后处理函数:process_exception(self, request, exception)

这个方法只有在 request 处理过程中出了问题并且view 函数抛出了一个未捕获的异常时才会被调用。这个钩子可以用来发送错误通知,将现场相关信息输出到日志文件,或者甚至尝试从错误中自动恢复。

这个函数的参数除了一贯的request对象之外,还包括view函数抛出的实际的异常对象exception 。

process_exception() 应当返回None或HttpResponse对象。

如果返回None,Django将用框架内置的异常处理机制继续处理相应request。

如果返回HttpResponse对象,Django将使用该response对象,而短路框架内置的异常处理机制。

Response后处理函数:process_response(self, request, response)

这个方法的调用时机在 Django 执行 view 函数并生成 response 之后。

该处理器能修改response 的内容;一个常见的用途是内容压缩,如gzip所请求的HTML页面。

这个方法的参数相当直观:request是request对象,而response则是从view中返回的response对象。

process_response() 必须返回 HttpResponse 对象. 这个 response 对象可以是传入函数的那一个原始对象(通常已被修改),也可以是全新生成的。

中间件执行流程

请求到达中间件之后,先按照正序执行每个注册中间件的process_request方法,process_request方法返回的值是None,就依次执行,如果返回的值是HttpResponse对象,不再执行后面的process_request方法,而是执行当前对应中间件的process_response方法(注意不是掉头执行所有的process_response方法),将HttpResponse对象返回给浏览器。也就是说:如果MIDDLEWARE中注册了6个中间件,执行过程中,第3个中间件返回了一个HttpResponse对象,那么第4,5,6中间件的process_request和process_response方法都不执行,顺序执行3,2,1中间件的process_response方法。

ZOZRu4.png

process_request方法都执行完后,匹配路由,找到要执行的视图函数,先不执行视图函数,先执行中间件中的process_view方法,process_view方法返回None,继续按顺序执行,所有process_view方法执行完后执行视图函数。假如中间件3 的process_view方法返回了HttpResponse对象,则4,5,6的process_view以及视图函数都不执行,直接从最后一个中间件,也就是中间件6的process_response方法开始倒序执行。

ZOZWDJ.png

MVC,MTV

MVC模式:程序不论简单或复杂,从结构上看,都可以分成三层

1.最上面的一层,是直接面向最终用户的”视图层”(View)。它是提供给用户的操作界面,是程序的外壳。
2.最底下的一层,是核心的”数据层”(Model),也就是程序需要操作的数据或信息
3.中间的一层,就是”控制层”(Controller),它负责根据用户从”视图层”输入的指令,选取”数据层”中的数据,然后对其进行相应的操作,产生最终结果

MTV模式:django中特有的模式

1.M: model, 相当于model层,和mvc中的m一样

2.T: Template, 相当于view层

3.V: view, 相当于controller层

Csrf攻击

CSRF(Cross-site request forgery)跨站请求伪造攻击,与XSS不同,XSS 利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。

1.用户C打开浏览器,访问受信任网站A,输入用户名和密码请求登录网站A;

2.在用户信息通过验证后,网站A产生Cookie信息并返回给浏览器,此时用户登录网站A成功,可以正常发送请求到网站A;

3.用户未退出网站A之前,在同一浏览器中,打开一个TAB页访问网站B;

4.网站B接收到用户请求后,返回一些攻击性代码,并发出一个请求要求访问第三方站点A;

5.浏览器在接收到这些攻击性代码后,根据网站B的请求,在用户不知情的情况下携带Cookie信息,向网站A发出请求。网站A并不知道该请求其实是由B发起的,所以会根据用户C的Cookie信息以C的权限处理该请求,导致来自网站B的恶意代码被执行。

防御这种攻击可以在请求地址中添加 token 并验证

csrf(跨站请求伪造)

先写一个简单的post请求,复现报错信息

钓鱼网站:银行转账的路径,你是否也可以拿到,然后你做一个跟银行一模一样的页面,也超银行的借口提交数据,当用户在钓鱼网站输入对方账户名和转账金额之后,点击发送。其实内部是将对方账户换成了钓鱼网站的造假人员的账户。造成你转账转错账户的情况

开两个django项目,模拟转账的现象

如何区分钓鱼网站和正经网站?在正经网站返回页面的时候,在form表单中偷偷塞一个特殊的字符串,后端记下改页面对应的字符串的值,等用户发post请求来的时候,我先去校验特殊的字符串是否匹配

如何去写这个特殊的字符串呢?模版语法有一个固定的写法{% csrf_token %},必须写在form表单内

浏览器查看改标签的值,并且每次都在刷新。再来演示刚刚转账的示例

ajax中如何设置csrf_token

# 第一种页面上先写一个{%csrf_token%}标签,后面用jquery查找标签取值组成键值对放入data中即可

csrf_token局部使用

# 只想给某个视图韩式加上csrf校验
from django.views.decorators.csrf import csrf_exempt,csrf_protect

# 局部禁用
@csrf_exempt
def index(request):
  pass

# 局部使用
@csrf_protect
def login(request):
  pass

# CBV比较特殊,不能单独加在某个方法上
# 只能加在类上或dispatch方法上
from django.utils.decorators import method_decorator
from django.views.decorators.csrf import csrf_exempt,csrf_protect
@method_decorator(csrf_exempt,name='get')  # 第一种
class Csrf_Token(View):
  @method_decorator(csrf_exempt)  # 第二种
  def dispatch(self,request,*args,**kwargs):
    res = super().dispatch(request,*args,**kwargs)
    return res
  @method_decorator(csrf_exempt)  # 这里这么写不行!!!
  def get(self,request):
    pass
  def post(self,request):
    pass
原文地址:https://www.cnblogs.com/yellowcloud/p/11365938.html