上下文处理器_自定义上下文处理器

上下文

1、上下文:Django视图函数传递给模板的数据叫做上下文(即content参数)

2、一般来说,一个视图函数传递给模板的数据(上下文),只能在该模板中使用,其他模板是不能使用这些数据的(模板之间无继承、引用关系)
    ⑴A模板引用了B模板,即,B模板中的HTML代码以"变量"的形式添加到A模板中,此时B模板就相当于是A模板中的一部分
    ⑵因此A模板视图函数传递给A模板的数据,在B模板中是可以使用的    
    ⑶注:即使C模板同时引用了B模板,但是C模板依旧不能使用A模板中的变量

3、URL、视图函数、模板之间的关系:
    ⑴一般情况下一个URL对应一个视图函数、一个视图函数对应一个模板
    ⑵视图函数传递给模板的数据(上下文)只能在视图函数对应的模板中使用,其他模板是不能使用这些数据的
    ⑶上下文数据(content参数)是在HttpResponse对象中与模板一起传递下来的,所以模板只能使用自己的上下文(其他模板都没有接受到这些数据,肯定就没法使用了)
    ⑷A视图函数对应(引用)a模板,B视图函数对应(引用)b模板,那么A视图函数传递给a模板的数据(content参数)就只能在a模板中使用,b模板是不能使用这些数据的
    
例1:
⑴编辑视图

上下文处理器_自定义上下文处理器

⑵编辑模板

上下文处理器_自定义上下文处理器

⑶编辑模板

上下文处理器_自定义上下文处理器

⑷编辑URL映射

上下文处理器_自定义上下文处理器

⑸访问:index页面

上下文处理器_自定义上下文处理器

⑹访问:demo页面

上下文处理器_自定义上下文处理器

注:
1、从上面的例子中可以看出:视图函数传递给模板的数据(上下文)只能在视图函数对应的模板中使用,其他模板是不能使用这些数据的
    ⑴当然还需要注意下:在模板中接收上下文时 所使用的的变量名是正确的(与视图函数中定义的键名一致)

2、如果有一些数据(上下文)在很多模板中都会用到,那么岂不是需要在每个视图函数中都获取一次,然后再传递给视图函数对应的模板了么?这样的话,岂不是代码重复率就会很高了。为了解决这个问题,就有了我们这里需要学习的"上下文处理器"

3、在编写Django视图函数时,我们一般会在视图函数中以Python字典(dict)形式向模板中传递需要被调用或使用的变量并指定渲染模板,通常情况下,我们向模板的传递的字典变量与模板是一一对应的关系

4、有时我们还需要向模板传递全局变量,即每个模板都需要使用到的变量(比如站点名称, 博客的最新文章列表)。如果每个视图函数分别去查询数据库,然后向每个模板传递这些变量,不仅造成代码冗余,而且会造成对数据库的重复查询。一个更好的解决方案就是使用自定义的上下文处理器(Context Processors)给模板传递全局变量,一次查询全局使用,完美解决了这些问题

 

什么是上下文处理器

1、上下文处理器是可以返回一些数据:这些数据在全局模板中都可以使用
    ⑴比如登录后的用户信息,在很多页面中都需要使用,那么我们就可以将这些用户信息放在上下文处理器中。需要用户信息的模板就直接获取这些数据就好了,就没有必要在每个视图函数中都返回这些数据

2、上下文处理器的用处:简而言之就是将我们多次重复使用的某个变量在上下文处理器中传给所有的模板,这样我们就不用再重复获取、传递这个变量了

 

自定义上下文处理器

1、有时候我们想要返回自己的数据。那么这时候我们可以自定义上下文处理器。自定义上下文处理器的步骤如下:
    ⑴可以根据这个上下文处理器是属于哪个app,然后在这个app中创建一个文件专门用来存储上下文处理器。比如context_processors.py。或者是你也可以专门创建一个Python包,用来存储所有的上下文处理器
    ⑵在你定义的上下文处理器文件中,定义一个函数,这个函数只有一个request参数。这个函数中处理完自己的逻辑后,把需要返回给模板的数据,通过字典的形式返回。如果不需要返回任何数据,那么也必须返回一个空的字典
    ⑶在settings.py文件中注册这个注册上下文处理器:settings.py->TEMPLATES->context_processors
    ⑷在模板中直接使用上面定义的变量就好了

例2:
⑴编辑上下文处理器

上下文处理器_自定义上下文处理器

⑵注册上下文处理器

上下文处理器_自定义上下文处理器

⑶编辑视图函数

上下文处理器_自定义上下文处理器

⑷编辑模板:index页面

上下文处理器_自定义上下文处理器

⑸编辑模板:demo页面

上下文处理器_自定义上下文处理器

⑹访问:index页面

上下文处理器_自定义上下文处理器

⑺访问:demo页面

上下文处理器_自定义上下文处理器

注:从上面例子中可以看到
1、上下文处理器中定义的变量(数据)是公共的,在所有模板中都可以直接使用,另外视图函数中也可以定义自己的数据(两者之间互不影响:分别以两个字典的形式传递给模板)
    ⑴上下文处理器中定义的变量是公共的,任意模板中可以选择用也可以选择不同(对视图函数和模板无任何影响)

2、视图函数中也可以定义自己的变量(数据)并传递给模板
    ⑴视图函数中定义的数据和上下文处理器中的数据也是互不影响,感觉两个数据是分别以不同的方式传递给模板的

3、上下文处理器中的数据,可以在任意应用程序中使用
    ⑴A应用程序中定义了一个上下文处理器数据,那么在B应用程序中也是可以使用的

4、只要定义了上下文处理器,那么:不管你访问哪个URL,都会执行URL本身对应的视图函数和上下文处理器函数(感觉是一个装饰器的作用:两个地方的数据互不影响)
    ⑴如果在模板中用到了上下文处理器的处理结果:那么就正常使用上下文处理器的处理结果和自己视图函数传递给自己模板的数据(两者之间互不影响:分别以两个字典的形式传递给模板)
    ⑵如果没用到上下文处理器的处理结果:那么上下文处理器也会执行和返回结果(只是在模板中没有用到),正常使用自己视图函数传递给自己模板的数据就好了

 

示例

1、一个网站中有很多页面,当用户进行登录后,所有的页面都会显示器登录信息(用户名)。这个就是比较经典的上下文处理器应用场景了

2、比如****网站:其首页有很多子页面跳转按钮(应用程序APP),只要进行了登录,那么不管我们切换到哪个页面,其都会显示用户信息(这里只截图了用户头像)

3、现在我们就要实现这么一个功能:
    ⑴主页面下有有很多子页面
    ⑵用户未登录时显示【登录】、【注册】
    ⑶用户登录后,就显示器用户名
    
例3:
⑴****页面

上下文处理器_自定义上下文处理器

⑵用户未登录时

上下文处理器_自定义上下文处理器

⑶用户登录后

上下文处理器_自定义上下文处理器


例4:
1、编辑URL映射

上下文处理器_自定义上下文处理器

2、编辑模型

上下文处理器_自定义上下文处理器

3、编辑注册表单:使用表单、模型分离模式

上下文处理器_自定义上下文处理器

4、编辑注册视图函数

上下文处理器_自定义上下文处理器

5、编辑公共模板

上下文处理器_自定义上下文处理器

6、编辑CSS文件:公共模板

上下文处理器_自定义上下文处理器

7、编辑注册模板

上下文处理器_自定义上下文处理器

8、编辑登录表单

上下文处理器_自定义上下文处理器

9、编辑登录视图

上下文处理器_自定义上下文处理器

10、编辑登录模板

上下文处理器_自定义上下文处理器

11、编辑首页视图

上下文处理器_自定义上下文处理器

11.1、用户名模板

上下文处理器_自定义上下文处理器

12、编辑首页模板

上下文处理器_自定义上下文处理器

13、编辑其他页面视图函数

上下文处理器_自定义上下文处理器

14、编辑博客模板

上下文处理器_自定义上下文处理器

15、编辑视屏模板

上下文处理器_自定义上下文处理器

16、未登录时访问首页

上下文处理器_自定义上下文处理器

17、未登录时访问其他页面

上下文处理器_自定义上下文处理器

18、登录后访问首页

上下文处理器_自定义上下文处理器

19、登录后访问其他页面

上下文处理器_自定义上下文处理器

20、编写上下文处理器

上下文处理器_自定义上下文处理器

21、注册上下文处理器

上下文处理器_自定义上下文处理器

22、重新编辑首页等视图函数

上下文处理器_自定义上下文处理器

23、4_登录后访问首页

上下文处理器_自定义上下文处理器

24、登录后访问视频页面

上下文处理器_自定义上下文处理器

25、登录后访问博客页面

上下文处理器_自定义上下文处理器

注:从上面例子中可以看到
1、上下文处理器中定义的变量(数据)是公共的,在所有模板中都可以直接使用,另外视图函数中也可以定义自己的数据(两个互不冲突)

2、只要定义了上下文处理器,那么:不管你访问哪个URL,都会执行URL本身对应的视图函数和上下文处理器函数(感觉上下文处理器就是一个装饰器的作用:两个地方的数据互不影响)
    ⑴如果在模板中用到了上下文处理器的处理结果:那么就正常使用上下文处理器的处理结果和自己视图函数传递给自己模板的数据(两者之间互不影响:分别以两个字典的形式传递给模板)
    ⑵如果没用到上下文处理器的处理结果:那么上下文处理器也会执行和返回结果(只是在模板中没有用到),正常使用自己视图函数传递给自己模板的数据就好了