django之ForNode是如何渲染的
django的模板编译后变成一般text、tag、varible,然后根据上下文进行渲染。
class ForNode(Node):
child_nodelists = ('nodelist_loop', 'nodelist_empty')
def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None):
self.loopvars, self.sequence = loopvars, sequence
self.is_reversed = is_reversed
self.nodelist_loop = nodelist_loop
if nodelist_empty is None:
self.nodelist_empty = NodeList()
else:
self.nodelist_empty = nodelist_empty
def __repr__(self):
reversed_text = ' reversed' if self.is_reversed else ''
return "<For Node: for %s in %s, tail_len: %d%s>" % \
(', '.join(self.loopvars), self.sequence, len(self.nodelist_loop),
reversed_text)
def __iter__(self):
for node in self.nodelist_loop:
yield node
for node in self.nodelist_empty:
yield node
def render(self, context):
if 'forloop' in context:#先判断是不是for循环
parentloop = context['forloop']
else:
parentloop = {}
with context.push():#调用context.push()会在栈顶放一个contextdict对象
try:
values = self.sequence.resolve(context, True)#找到可迭代的对象
except VariableDoesNotExist:
values = []
if values is None:
values = []
if not hasattr(values, '__len__'):
values = list(values)
len_values = len(values)
if len_values < 1:
return self.nodelist_empty.render(context)
nodelist = []
if self.is_reversed:
values = reversed(values)
num_loopvars = len(self.loopvars)#判断loop变量个数
unpack = num_loopvars > 1
# Create a forloop value in the context. We'll update counters on each
# iteration just below.
loop_dict = context['forloop'] = {'parentloop': parentloop}#loop_dict与context['forloop']是同一个词典,loop_dict['counter0'] = i后,通过context['forloop']可以访问到loop_dict
for i, item in enumerate(values):
# Shortcuts for current loop iteration number.
loop_dict['counter0'] = i#每次循环时counter0的值都会变化,可以在模板文件上使用
loop_dict['counter'] = i + 1
# Reverse counter iteration numbers.
loop_dict['revcounter'] = len_values - i
loop_dict['revcounter0'] = len_values - i - 1
# Boolean values designating first and last times through loop.
loop_dict['first'] = (i == 0)
loop_dict['last'] = (i == len_values - 1)
pop_context = False
if unpack:
# If there are multiple loop variables, unpack the item into
# them.
# To complete this deprecation, remove from here to the
# try/except block as well as the try/except itself,
# leaving `unpacked_vars = ...` and the "else" statements.
if not isinstance(item, (list, tuple)):
len_item = 1
else:
len_item = len(item)
# Check loop variable count before unpacking
if num_loopvars != len_item:
warnings.warn(
"Need {} values to unpack in for loop; got {}. "
"This will raise an exception in Django 1.10."
.format(num_loopvars, len_item),
RemovedInDjango110Warning)
try:
unpacked_vars = dict(zip(self.loopvars, item))
except TypeError:
pass
else:
pop_context = True
context.update(unpacked_vars)
else:
context[self.loopvars[0]] = item#在上下文中增加变量,为后面的node渲染提供数据
for node in self.nodelist_loop:
nodelist.append(node.render_annotated(context))
if pop_context:
# The loop variables were pushed on to the context so pop them
# off again. This is necessary because the tag lets the length
# of loopvars differ to the length of each set of items and we
# don't want to leave any vars from the previous loop on the
# context.
context.pop()
return mark_safe(''.join(force_text(n) for n in nodelist))
context每次调用push函数后都会改变context的dicts列表。解析一个node时,都会有一个上下文。相当于一个新的环境。
django之ForNode是如何渲染的的更多相关文章
- Django基础学习六之渲染
今天简单的介绍一下Django的template的渲染和Django的template的基本的语法 首先我们先启动一个django的shell,首先需要进入django的工程目录下启动django的s ...
- Django学习笔记之模板渲染、模板语言、simple_tag、母版子版、静态配置文件
一.首先我们用PyCharm来创建一个Django项目 终端命令:django-admin startproject sitename 图形创建: 这样一个Django项目就创建完成了,上面可以看 ...
- Django 命令行调用模版渲染
首先我们需要进入 Django 的 shell python manage.py shell 渲染模版中的 name from django.template import Context,Templ ...
- Django路由分配以及模版渲染
路由上: 在网络上区分不同的电脑通过IP.端口和网卡的MAC地址等,在web框架中怎么区分不同的请求呢,就是通过 ‘url(路由)’ ,url 学名叫做全球统一资源定位符,其实就是一个网址 一个url ...
- django 第四天模板渲染
今日内容 一.模板渲染 语法 {{ 变量 }} {% 逻辑 %} 1.变量 取列表中的第几个元素,用索引 <p>{{ namelist.2 }}</p> 取字典中的第几个元素用 ...
- 「Django」rest_framework学习系列-渲染器
渲染器:作用于页面,JSONRenderer只是JSON格式,BrowsableAPIRenderer有页面,.AdminRenderer页面以admin形式呈现(需要在请求地址后缀添加?fromat ...
- Django rest-framework框架-组件之渲染器
渲染器: from rest_framework.renderers import BrowsableAPIRenderer,AdminRenderer,HTMLFormRenderer,JSONRe ...
- Django(51)drf渲染模块源码分析
前言 渲染模块的原理和解析模块是一样,drf默认的渲染有2种方式,一种是json格式,另一种是模板方式. 渲染模块源码入口 入口:APIView类中dispatch方法中的:self.response ...
- Django学习路29_css样式渲染 h3 标签
在 static 静态文件夹下创建 css 文件夹 home.css 此时 home.css 路径是 'static/css/home.css' 在 对应的 home.html 文件中添加 css 样 ...
随机推荐
- 基于Kafka消息驱动最终一致事务(二)
实现用例分析 上篇基于Kafka消息驱动最终一致事务(一)介绍BASE的理论,接着我们引入一个实例看如何实现BASE,我们会用图7显示的算法实现BASE.
- 其他类想使用unittest的断言方法,就import unittest的框架,继承他,使用他里面的方法
在断言层 也可以同样用这个方法
- 【ZZ】谈谈持续集成,持续交付,持续部署之间的区别
谈谈持续集成,持续交付,持续部署之间的区别 http://blog.flow.ci/cicd_difference/ 谈谈持续集成,持续交付,持续部署之间的区别 2016年08月03日 标签:beta ...
- IP段,ASN与BGP之间的关系
概览 IP段就是类似于1.0.2.0-1.0.2.255或者1.0.2.0/24的形式 ASN(Autonomous system number)自治系统编号 BGP(Border Gateway P ...
- github_源码
固定头部: hongyangAndroid/Android-StickyNavLayout:ListView 与ViewPager 滑动冲突处理,滑动到顶部固定位置停顿; ufo22940268/ ...
- 第1章 计算机网络和协议(3)_TCP/IP协议
3. TCP/IP协议 3.1 TCP/IP协议分层 3.2 TCP/IP通信过程 (1)应用层:浏览器和Web服务器是两个对等的实现,它们之间使用http协议进行通信. (2)传输层:网页传输之前, ...
- (转)先装VS后装IIS产生问题的解决办法
原文地址:http://www.cnblogs.com/mytechblog/articles/1897682.html 基于.net的web程序设计asp.net,我们就必须安装VS和IIS,但这二 ...
- hadoop分布式集群的搭建
电脑如果是8G内存或者以下建议搭建3节点集群,如果是搭建5节点集群就要增加内存条了.当然实际开发中不会用虚拟机做,一些小公司刚刚起步的时候会采用云服务,因为开始数据量不大. 但随着数据量的增大才会考虑 ...
- three.js学习:初学three.js,从立方体开始
目前three.js是浏览器展现3D效果的一个很强大的js工具,遗憾的是没有特别系统而全面的文档(threejs官方文档感觉有些缺漏,可以和WebGL中文网的threejs教程对比着看).好了,根据W ...
- linux杂项
重装后激活root帐号并设置密码 sudo passwd root sudo: netstat:找不到命令 安装net-tools:sudo apt-get install net-tools Com ...