DAY3
【知识回顾】过滤器
作用: 对变量进行过滤。在真正渲染出来之前,过滤器会根据功能处理好变量,然后得出结果后再替换掉原来的变量展示出来。
语法:{{fruits|lower}}
管道符号进行链式调用,比如实现一个功能,先把所有字符变成小写,把第一个字符转换成大写。
语法:{{fruits|lower|capfirst}}
使用参数:过滤器可以使用参数,在过滤器名称后面使用冒号”:”再加上参数,比如要把一个字符串中所有的空格去掉,则可以使用cut过滤器,
语法如下: {{fruits|cut:” “}}
注意:
使用参数的时候,冒号和参数之间不能有任何空格,一定要紧挨着
常用标签
什么是标签?
在模板渲染的过程中提供任意逻辑;
这个定义是刻意模糊的。 例如,一个标签可以输出内容,作为控制结构,例如“if”语句或“for”循环从数据库中提取内容,甚至可以访问其他的模板标签;
标签语法: 由%}和 {%来定义的,例如:
{%tag%} {%endtag%};
常用标签
【补充】子应用的创建
1,在该路径激活虚拟环境—-Scripts下
C:\Users\tylor\Documents\项目管理\duplicate\tzblog\Scripts>activate
2, 创建子应用的路径—-项目路径下
C:\Users\tylor\Documents\项目管理\duplicate\tzblog\Scripts\tzlook>tree /f
3,在tzlook/settings.py下注册app
【注意】在settings下配置apps的名字,可以从子应用的app下找到
INSTALLED_APPS = ['django.contrib.admin','django.contrib.auth', # 用户与权限认证应用'django.contrib.contenttypes', # 为Model提供更高层次抽象接口应用,被auth依赖'django.contrib.sessions', # 保存用户状态的会话应用'django.contrib.messages', # 消息应用'django.contrib.staticfiles','look.apps.LookConfig','book.apps.BookConfig',]
模板的继承
【组件】
三个HTML文件:base, indexx, ss
【代码】
base.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>{% block title %} 这是默认标题{% endblock %}</title></head><body>{% block content %}这是默认内容{% endblock %}{% block demo %}这是默认演示{% endblock %}</body></html>
indexx.html
{% extends 'base.html' %}{% block title %}主页{% endblock %}{% block content %}这是通过blocksuper继承的父类:{{block.super}}<br>{% endblock %}{% block demo %}这是通过include 引用的其他模板的内容:{% include 'ss.html' %}{% endblock %}
ss.html
<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>内容</title></head><body>潭州教育python学院 Djano框架班</body></html>
【效果展示】
【】
【】
模板的引用
步骤:
首先在tzlook/template创建名为look的HTML5文件
然后在tzlook/urls.py中导入tzlook/book.urls路径
其次在tzlook/book/urls中调用book/views视图
【注意】需要导入应用的views文件
在book/views中书写类,同时调用html5文件
【注意】需要在视图函数中导入渲染器;
总结
【tips】location : django/template/base.py
【source code】—- example of using template
The Template class is a convenient wrapper that takes care of templatecompilation and rendering.Usage:The only thing you should ever use directly in this file is the Template class.Create a compiled template object with a template_string, then call render()with a context. In the compilation stage, the TemplateSyntaxError exceptionwill be raised if the template doesn't have proper syntax.Sample code:>>> from django import template>>> s = '<html>{% if test %}<h1>{{ varvalue }}</h1>{% endif %}</html>'>>> t = template.Template(s)(t is now a compiled template, and its render() method can be called multipletimes with multiple contexts)>>> c = template.Context({'test':True, 'varvalue': 'Hello'})>>> t.render(c)'<html><h1>Hello</h1></html>'>>> c = template.Context({'test':False, 'varvalue': 'Hello'})>>> t.render(c)'<html></html>'"""
【source code】definition of template
class Template:def __init__(self, template_string, origin=None, name=None, engine=None):# If Template is instantiated(illustrate) directly rather than from an Engine and# exactly one Django template engine is configured, use that engine.# This is required to preserve backwards-compatibility[兼容性] for direct use# e.g. Template('...').render(Context({...}))if engine is None:from .engine import Engineengine = Engine.get_default()if origin is None:origin = Origin(UNKNOWN_SOURCE)self.name = nameself.origin = originself.engine = engineself.source = template_stringself.nodelist = self.compile_nodelist()def __iter__(self):for node in self.nodelist:yield from nodedef _render(self, context):return self.nodelist.render(context)def render(self, context):"Display stage -- can be called many times"with context.render_context.push_state(self):if context.template is None:with context.bind_template(self):context.template_name = self.namereturn self._render(context)else:return self._render(context)def compile_nodelist(self): # Nodelist is similar as array"""Parse and compile the template source into a nodelist. If debugis True and an exception occurs during parsing, the exception isis annotated with contextual line information where it occurred in thetemplate source."""if self.engine.debug:lexer = DebugLexer(self.source) # lexer---词法分析程序else:lexer = Lexer(self.source)tokens = lexer.tokenize()parser = Parser(tokens, self.engine.template_libraries, self.engine.template_builtins,self.origin,)try:return parser.parse()except Exception as e:if self.engine.debug:e.template_debug = self.get_exception_info(e, e.token)raisedef get_exception_info(self, exception, token):"""Return a dictionary containing contextual line information of wherethe exception occurred in the template. The following information isprovided:messageThe message of the exception raised.source_linesThe lines before, after, and including the line the exceptionoccurred on.lineThe line number the exception occurred on.before, during, afterThe line the exception occurred on split into three parts:1. The content before the token that raised the error.2. The token that raised the error.3. The content after the token that raised the error.totalThe number of lines in source_lines.topThe line number where source_lines starts.bottomThe line number where source_lines ends.startThe start position of the token in the template source.endThe end position of the token in the template source."""start, end = token.positioncontext_lines = 10line = 0upto = 0source_lines = []before = during = after = ""for num, next in enumerate(linebreak_iter(self.source)):if start >= upto and end <= next:line = numbefore = escape(self.source[upto:start])during = escape(self.source[start:end])after = escape(self.source[end:next])source_lines.append((num, escape(self.source[upto:next])))upto = nexttotal = len(source_lines)top = max(1, line - context_lines)bottom = min(total, line + 1 + context_lines)# In some rare cases exc_value.args can be empty or an invalid# string.try:message = str(exception.args[0])except (IndexError, UnicodeDecodeError):message = '(Could not get exception message)'return {'message': message,'source_lines': source_lines[top:bottom],'before': before,'during': during,'after': after,'top': top,'bottom': bottom,'total': total,'line': line,'name': self.origin.name,'start': start,'end': end,}
【technique】How to read specific source code

【definition of Context】location: django/template/context.py
class RenderContext(BaseContext):"""A stack container for storing Template state.RenderContext simplifies the implementation【执行】 of template Nodes by providing asafe place to store state between invocations【d】 of a node's `render` method.The RenderContext also provides scoping rules that are more sensible for'template local' variables. The render context stack is pushed before eachtemplate is rendered, creating a fresh scope with nothing in it. Nameresolution fails if a variable is not found at the top of the RequestContextstack. Thus, variables are local to a specific template and don't affect therendering of other templates as they would if they were stored in the normaltemplate context."""template = Nonedef __iter__(self):yield from self.dicts[-1]def __contains__(self, key):return key in self.dicts[-1]def get(self, key, otherwise=None):return self.dicts[-1].get(key, otherwise)def __getitem__(self, key):return self.dicts[-1][key]
【Context_processor】definition
"""A set of request processors that return dictionaries to be merged into atemplate context. Each function takes the request object as its only parameterand returns a dictionary to add to the context.These are referenced from the 'context_processors' option of the configurationof a DjangoTemplates backend and used by RequestContext."""import itertoolsfrom django.conf import settingsfrom django.middleware.csrf import get_tokenfrom django.utils.functional import SimpleLazyObject, lazydef csrf(request):"""Context processor that provides a CSRF token, or the string 'NOTPROVIDED' ifit has not been provided by either a view decorator or the middleware"""def _get_val():token = get_token(request)if token is None:# In order to be able to provide debugging info in the# case of misconfiguration, we use a sentinel[哨兵] value# instead of returning an empty dict.return 'NOTPROVIDED'else:return tokenreturn {'csrf_token': SimpleLazyObject(_get_val)}def debug(request):"""Return context variables helpful for debugging."""context_extras = {}# 当前的项目处于DEBUG模式且请求的IP地址位于INTERNAL_IPS中if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:# 用于标记当前处于DEBUG模式context_extras['debug'] = Truefrom 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)# sql_queries是列表,记录一次清酒发生的SQL查询和每次查询的耗时return context_extrasdef i18n(request):from django.utils import translationreturn {'LANGUAGES': settings.LANGUAGES,'LANGUAGE_CODE': translation.get_language(),'LANGUAGE_BIDI': translation.get_language_bidi(),}def tz(request):from django.utils import timezonereturn {'TIME_ZONE': timezone.get_current_timezone_name()}def static(request):"""Add static-related context variables to the context."""return {'STATIC_URL': settings.STATIC_URL}def media(request):"""Add media-related context variables to the context."""return {'MEDIA_URL': settings.MEDIA_URL}def request(request):return {'request': request}
【supplement】
backup
<a href="#">{{name|cut:" "}}约么?</a><a href="#">{{protagonist}}约</a><a href="#">{{name}}去哪里?</a><h1>这部分代码将要演示模板变量</h1>这个变量是字符串对象:{{books_name}}<br>这个变量是函数对象:{{hello}}<br>这个变量是类方法对象:{{fruit.name}}<br>这个变量是类对象,访问类对象的属性: {{fruit.say}}<br>这个变量是列表对象:{{ list }}<br>这个变量是列表对象,访问列表的元素{{list.1 }}<br>这个变量是字典对象:{{dict}}<br>这个变量是字典对象,访问字典的键{{dict.a }}<br>
【匿名用户】
# PermWrapper[权限包装器] and PermLookupDict[权限查看字典] proxy the permissions system into objects that# the template system can understand.class PermLookupDict:def __init__(self, user, app_label):self.user, self.app_label = user, app_labeldef __repr__(self):return str(self.user.get_all_permissions())def __getitem__(self, perm_name):return self.user.has_perm("%s.%s" % (self.app_label, perm_name))def __iter__(self):# To fix 'item in perms.someapp' and __getitem__ interaction we need to# define __iter__. See #18979 for details.raise TypeError("PermLookupDict is not iterable.")def __bool__(self):return self.user.has_module_perms(self.app_label)class PermWrapper:def __init__(self, user):self.user = userdef __getitem__(self, app_label):return PermLookupDict(self.user, app_label)def __iter__(self):# I am large, I contain multitudes.raise TypeError("PermWrapper is not iterable.")def __contains__(self, perm_name):"""Lookup by "someapp" or "someapp.someperm" in perms."""if '.' not in perm_name:# The name refers to module.return bool(self[perm_name])app_label, perm_name = perm_name.split('.', 1)return self[app_label][perm_name]def auth(request):"""Return context variables required by apps that use Django's authenticationsystem.If there is no 'user' attribute in the request, use AnonymousUser (fromdjango.contrib.auth)."""if hasattr(request, 'user'):user = request.userelse:from django.contrib.auth.models import AnonymousUser[匿名用户]user = AnonymousUser()return {'user': user,'perms': PermWrapper(user),}
