上下文处理器

上下文处理器可以返回一些数据,在全局模板中都可以使用,比如登录后的用户数据,在很多页面中都需要使用,那么我们就可以方在上下文处理器中,就没有必要在每个视图中返回这个对象了。
在settings.py.TEMPLATES.OPTIONS.context_processors中,有许多内置的上下文处理器,这些上下文处理器的作用如下:

(1)django.template.context_processors.debug:增加一个debug和sql_queries变量,在模板中可以通过他来查看到一些数据库查询。

查看一下debug函数的定义,示例代码如下:

def debug(request):
"""
Return context variables helpful for debugging.
"""
context_extras = {}
if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
context_extras['debug'] = True
from django.db import connections
# Return a lazy reference that computes connection.queries on access,
# to ensure it contains queries triggered after this function runs.
context_extras['sql_queries'] = lazy(
lambda: list(itertools.chain.from_iterable(connections[x].queries for x in connections)),
list
)
return context_extras
分析:首先会先判断debug是否为True,并且判断request.META.get('REMOTE_ADDR')是否在 settings.INTERNAL_IPS,因此,我们可以在settings.py中定义:INTERNAL_IPS = ['127.0.0.1'],如果两个都为True,就将定义的context_extras中的debug置为True,也对sql_queries做相应的操作。
因此,我们可以在index视图函数中,执行一些sql语句,然后在模板中查看是否内置的django.template.context_processors.debug是否为模板添加了debug和sql_queries变量。
def index(request):
<!--index视图函数执行相关sql语句-->
users = User.objects.all()
# 使用all()方法得到QuerySet对象,并没有执行sql语句
# 如果想要执行sql语句的话,可以通过遍历
for user in users:
print(user)
return render(request,'static/index.html')
在index.html模板中查看debug和sql_queries变量。
{{ debug }}/{{ sql_queries }}
之后在浏览器中,输入url就会显示出debug为True,并且也会显示出当前执行sql语句。

(2)django.template.context_processors.request:增加一个request变量,这个request变量也就是在视图函数中传入的第一个参数。

这个request对象就是之前我们说过的WSGIRequest对象,这个对象常用的属性都是只读的,我们可以根据request对象上的一些属性从客户端获取一些数据,示例代码如下:
<!--在index.html模板中-->
<!--比如我们可以使用request对象的path属性,获取服务器的完整“路径”,-->
{{ request.path }} <!--获取浏览器中的所有cookie-->
<p>{{ request.COOKIES }}</p>

(3)django.contrib.auth.context_processors.auth:Django内置的用户系统,这个上下文处理器会增加一个auth对象。所以,我们在使用自定义的处理器的时候,一定不要为context[]中的key设置为user,否者的话,Django就不知道到底是哪个user了。查看auth函数的定义,示例代码如下:

def auth(request):
if hasattr(request, 'user'):
user = request.user
else:
from django.contrib.auth.models import AnonymousUser
user = AnonymousUser() return {
'user': user,
'perms': PermWrapper(user),
}
分析:如果用户在request中没有传递user,就从django.contrib.auth.models中导入AnonymousUser,实例化一个user对象。

(4)django.contrib.messages.context_processors.messages:增加一个message变量。查看messages()函数的定义,示例代码如下:

def messages(request):
"""
Return a lazy 'messages' context variable as well as
'DEFAULT_MESSAGE_LEVELS'.
"""
return {
'messages': get_messages(request),
'DEFAULT_MESSAGE_LEVELS': DEFAULT_LEVELS,
}
(1).通过messages变量,我们可以返回给用户一些错误消息message和错误级别message.tags,可以通过from django.contrib import messages模块,可以利用messages模块上的add_messages()方法,为messages添加信息(包括提示、警告等)。而info()方法,可以为messages添加提示信息。示例代码如下:
 messages.add_message(request, messages.INFO, '用户名或密码输入有误')
等同于:
messages.info(request, '用户名或密码输入有误')
(2). 在模板中就可以遍历错误信息,进行显示。
<tr>
<td></td>
<td>
<ul>
{% for message in messages %}
<li>{{ message.tags }}{{ message }}</li>
{% endfor %}
</ul>
</td>
</tr>
(3). 可以对错误信息进行简单的提取,在forms.py文件中,为表单类定义一个函数,示例代码如下:
    def get_errors(self):
errors = super(SigninForm, self).errors.get_json_data()
new_errors = []
for messages in errors.values():
for message_dict in messages:
for key,value in message_dict.items():
if key == "message":
new_errors.append(value)
return new_errors

(5)django.template.context_processors.media:在模板中读取MEDIA_URL,比如想要在模板中使用上传的文件,那么这时候就需要使用settings.py中设置的MEDIA_URL来拼接url,示例代码如下:

(1)在settings.py文件中配置:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')]
,
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
<!--添加media上下文处理器-->
'django.template.context_processors.media',
],
},
},
] MEDIA_ROOT = [
os.path.join(BASE_DIR, 'media')
] MEDIA_URL = '/media/'
(2)在urls.py文件中,拼接media中上传的文件的url。
from django.urls import path
from front import views
from front.views import Signup, Signin
from django.conf.urls.static import static
from django.conf import settings urlpatterns = [
path('', views.index, name='index'),
path('signin/', Signin.as_view(), name='signin'),
path('signup/', Signup.as_view(), name='signup'),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
(3)在模板中:
    <img src="{{ MEDIA_URL }}time.jpg" />

不知道为什么老是会报错:TypeError: expected str, bytes or os.PathLike object, not list

[18/Feb/2020 19:38:00] "GET /media/time.jpg HTTP/1.1" 500 83742,可是在media中有time.jpg啊? 怎么回事呢?

(6)django.template.context_processors.static:在模板中使用STATIC_URL。

django.template.context_processors.static和django.template.context_processors.media的用法相同。

(7)django.template.context_processors.csrf:生成一个可以在模板中使用的csrf_token变量。示例代码如下:

<form action="" method="post">
<!--value可以使用中间件中提供的一个变量csrf_token-->
<input type="hidden" name="csrfmiddlewaretoken" value="{{ csrf_token }}">
<table>
<tr>
<td>用户名:</td>
<td><input type="text" name="username"></td>
</tr>
<tr>
<td>密码:</td>
<td><input type="password" name="password"></td>
</tr>
<tr>
<td>确认密码:</td>
<td><input type="password" name="password_repeat"></td>
</tr>
<tr>
<td>手机号:</td>
<td><input type="text" name="telephone"></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="提交"></td>
</tr>
</table>
</form>
并且需要在settings.py文件中的TEMPLATES->OPTIONS->context_processors中添加“django.template.context_processors.csrf”,此时在向网站中提交数据时,就不会出现csrf禁止了。

如果是在模板中需要使用csrf_token变量,我们可以使用{% csrf_token %}标签来生成一个csrf_token的input标签(可以通过查看网页源代码查看),这样同样可以达到相同的效果。而不需要再配置settings.py文件中的csrf的上下文处理器,并且在form表单提交表单内容之前,手动添加一个csrf的input标签。

141.内置上下文处理器debug、request、auth、messages、media、static、csrf的更多相关文章

  1. JSP内置对象——out对象/request对象

    在这个科技高速发展的时代,迫使我们的脚步一刻都不能停下. 在这个for循环语句当中,我们可以直接使用jsp内置对象中的out对象来给浏览器打印输出,那么这个out对象就是一个内置对象, 在这里,我们使 ...

  2. JSP内置九个对象Request请求对象

    jsp内置对象是什么呢? 例如Java语言使用一个对象之前需要实例化(也就是所说的new一个对象),创建对象这个过程有点麻烦,所以在jsp中提供了一些内置对象,用来实现很多jsp应用.在使用内置对象时 ...

  3. JSP内置对象1(request,response,session)

    request对象 response对象:请求重定向与请求转发的区别. session对象:表示客户端与服务器的一次会话,也就是用户浏览网站所花费的时间.在服务器的内存中保存着不同用户的session ...

  4. Python3 内置http.client,urllib.request及三方库requests发送请求对比

    如有任何学习问题,可以添加作者微信:lockingfree 更多学习资料请加QQ群: 822601020获取 HTTP,GET请求,无参 GET http://httpbin.org/get Pyth ...

  5. django上下文处理器

    上下文处理器(context processors)上下文处理器是可以返回一些数据,在全局模板中都可以使用.比如登录后的用户信息,在很多页面中都需要使用,那么我们可以放在上下文处理器中,就没有必要在每 ...

  6. 二、JSP的3个编译指令,7个动作指令,9个内置对象

    JSP 3个编译指令 1)  page指令(基本不需要用到,使用默认即可) 主要属性: 1.Language:指定脚本所采用的语言类型,现在只支持java 2.Extends:定义当前jsp产生的se ...

  7. Jsp(3):内置对象和四种域对象的理解

    由来:在jsp开发中,会频繁使用到一些对象 .例如HttpSession,ServletContext,ServletContext,HttpServletRequet.所以Sun公司设计Jsp时,在 ...

  8. jsp九个内置对象、四个域对象及Servlet的三大域对象

    一,什么是内置对象? 在jsp开发中会频繁使用到一些对象,如ServletContext HttpSession PageContext等.如果每次我们在jsp页面中需要使用这些对象都要自己亲自动手创 ...

  9. jsp中9个内置对象与servlet对应关系及四个作用域

    参考:  <jsp&servlet学习笔记.第2版.林信良><JSR-245 JavaServer Pages 2.2 Maintenance Release Specifi ...

随机推荐

  1. centos7利用系统镜像修复grub

    1 故障描述 由于错误操作,导致grub配置文件失效,系统开机后一直卡在下面的画面. 2 解决办法 这时候,就要利用系统镜像光盘,进入修复模式,然后按下面图示操作 进入镜像的shell环境,如下图所示 ...

  2. 4.【Spring Cloud Alibaba】服务容错-sentinel

    雪崩效应 常见容错方案 超时 限流 仓壁模式 断路器模式 断路器三态转换 使用Sentinel实现容错 什么是Sentinel https://github.com/alibaba/Sentinel ...

  3. 珠峰-buffer-流事件

    #### Buffer // 字符串的二进制转10进制 let r = parseInt('11111111', 2); console.log(r); // 打印 255 // Number类型转为 ...

  4. vue路由--动态路由

    前面介绍的路由都是路径和组件一对一映射的 有时候需要多个路径映射到一个组件,这个组件根据参数的不同动态改变,这时候需要用到动态路由 动态路由这样定义路由路径: path: '/foo/:id'--可以 ...

  5. 双向绑定Proxy VS Object.defineProperty

    Vue3.0的双向绑定将使用Proxy代替Object.defineProperty,据尤大说,速度提升了1倍. 本文我们来探讨一下Proxy对比Object.defineProperty究竟有哪些优 ...

  6. 《ASP.NET Core应用开发入门教程》与《ASP.NET Core 应用开发项目实战》正式出版

    “全书之写印,实系初稿.有时公私琐务猬集,每写一句,三搁其笔:有时兴会淋漓,走笔疾书,絮絮不休:有时意趣萧索,执笔木坐,草草而止.每写一段,自助覆阅,辄摇其首,觉有大不妥者,即贴补重书,故剪刀浆糊乃不 ...

  7. Electron – 基础学习(3): 项目打包成exe桌面应用 之electron-builder

    前次用 electron-packager 打包成功,这次改用 electron-builder 打包,然后根据项目中实际需要进行选择使用. 第一步:全局安装 electron-builder,便于系 ...

  8. Android Studio 学习笔记(四):Adapter和RecyclerView说明

    在现版本中,滚动控件有多种,而相比于ListView,GridView,RecyclerView的用途更广,因此将前两者作为Adapter适配器的引入,再对RecyclerView进行简单讲解. MV ...

  9. 从零构建Flink SQL计算平台 - 1平台搭建

    一.理想与现实 Apache Flink 是一个分布式流批一体化的开源平台.Flink 的核心是一个提供数据分发.通信以及自动容错的流计算引擎.Flink 在流计算之上构建批处理,并且原生的支持迭代计 ...

  10. Linux学习Day4:管道符、重定向与环境变量

    仅仅是学习Linux系统的命令还不够,只有把多个命令按照自己想要的方式进行组合使用,才能提高工作效率.今天的内容主要是关于如何把命令组合在一起使用,使得输入的命令更准确.更高效,也为接下来的Shell ...