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 样 ...
随机推荐
- 【sql】之case when then else end
select a.`name`, sum(( END)) '语文', sum(( END)) '数学', sum(( END))'英语' from t_score a GROUP BY a.`name ...
- 【剑指offer】规则二维数组查找
在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数. 思路: ...
- P2799国王的魔镜
链接 想了好久(蒟蒻的不能蒟蒻) 题解: #include<iostream>#include<cstdio>#include<cstring>#include&l ...
- java设计模式-工厂系列
一.简单工厂 1.背景: 任意定制交通工具的类型和生产过程 代码: Moveable.java package com.cy.dp.factory; public interface Moveable ...
- 廖雪峰Java5Java集合-5Queue-1使用Queue
Queue特性和基本方法 Queue实现一个先进先出(FIFO, First In First Out)的队列.如收银台排队支付. Java中LinkedList实现了Queue接口,可以直接把Lin ...
- 记录Linux下解压大文件时的一次奇葩经历
由于需要安装新的系统,使用wget下载tar包,8G多下载了1个多小时.解压完后的文件夹中的tar包数量明显不够,而且原始的tar包竟然不见了. 同样的操作又进行了一次,结果还是一样,不得不怀疑是哪里 ...
- angular的subscribe
angular中可以使用observable和subscribe实现订阅,从而实现异步. 这里记录一个工作中的小问题,以加深对subscribe的理解.前端技能弱,慢慢积累中. 本来希望的是点击一个按 ...
- datetime模块常用功能小结
- [UE4]裁剪 Clipping
Clipping裁剪,是每个UI都有的属性.一般是在容器UI上设置,对容器内的UI进行裁剪. 一.Clip to Bounds:裁剪到边界 二.Clip To Bounds - Without Int ...
- UE4 几个好用的插件和Wiki教程
转自:http://blog.csdn.net/u014532636/article/details/72729881 https://github.com/ue4plugins/LoadingScr ...