DAY3

【知识回顾】过滤器

作用: 对变量进行过滤。在真正渲染出来之前,过滤器会根据功能处理好变量,然后得出结果后再替换掉原来的变量展示出来。

语法:{{fruits|lower}}

管道符号进行链式调用,比如实现一个功能,先把所有字符变成小写,把第一个字符转换成大写。

语法:{{fruits|lower|capfirst}}
使用参数:过滤器可以使用参数,在过滤器名称后面使用冒号”:”再加上参数,比如要把一个字符串中所有的空格去掉,则可以使用cut过滤器,

语法如下: {{fruits|cut:” “}}
注意:
使用参数的时候,冒号和参数之间不能有任何空格,一定要紧挨着

常用标签

什么是标签?

在模板渲染的过程中提供任意逻辑;

这个定义是刻意模糊的。 例如,一个标签可以输出内容,作为控制结构,例如“if”语句或“for”循环从数据库中提取内容,甚至可以访问其他的模板标签;

标签语法: 由%}和 {%来定义的,例如:

  1. {%tag%} {%endtag%};

常用标签

【补充】子应用的创建

1,在该路径激活虚拟环境—-Scripts下

  1. C:\Users\tylor\Documents\项目管理\duplicate\tzblog\Scripts>activate

2, 创建子应用的路径—-项目路径下

  1. C:\Users\tylor\Documents\项目管理\duplicate\tzblog\Scripts\tzlook>tree /f

3,在tzlook/settings.py下注册app

【注意】在settings下配置apps的名字,可以从子应用的app下找到

  1. INSTALLED_APPS = [
  2. 'django.contrib.admin',
  3. 'django.contrib.auth', # 用户与权限认证应用
  4. 'django.contrib.contenttypes', # 为Model提供更高层次抽象接口应用,被auth依赖
  5. 'django.contrib.sessions', # 保存用户状态的会话应用
  6. 'django.contrib.messages', # 消息应用
  7. 'django.contrib.staticfiles',
  8. 'look.apps.LookConfig',
  9. 'book.apps.BookConfig',
  10. ]

模板的继承

【组件】

三个HTML文件:base, indexx, ss

【代码】

base.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>{% block title %} 这是默认标题{% endblock %}</title>
  6. </head>
  7. <body>
  8. {% block content %}
  9. 这是默认内容
  10. {% endblock %}
  11. {% block demo %}
  12. 这是默认演示
  13. {% endblock %}
  14. </body>
  15. </html>

indexx.html

  1. {% extends 'base.html' %}
  2. {% block title %}主页{% endblock %}
  3. {% block content %}
  4. 这是通过blocksuper继承的父类:{{block.super}}<br>
  5. {% endblock %}
  6. {% block demo %}
  7. 这是通过include 引用的其他模板的内容:{% include 'ss.html' %}
  8. {% endblock %}

ss.html

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <title>内容</title>
  6. </head>
  7. <body>
  8. 潭州教育python学院 Djano框架班
  9. </body>
  10. </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

  1. The Template class is a convenient wrapper that takes care of template
  2. compilation and rendering.
  3. Usage:
  4. The only thing you should ever use directly in this file is the Template class.
  5. Create a compiled template object with a template_string, then call render()
  6. with a context. In the compilation stage, the TemplateSyntaxError exception
  7. will be raised if the template doesn't have proper syntax.
  8. Sample code:
  9. >>> from django import template
  10. >>> s = '<html>{% if test %}<h1>{{ varvalue }}</h1>{% endif %}</html>'
  11. >>> t = template.Template(s)
  12. (t is now a compiled template, and its render() method can be called multiple
  13. times with multiple contexts)
  14. >>> c = template.Context({'test':True, 'varvalue': 'Hello'})
  15. >>> t.render(c)
  16. '<html><h1>Hello</h1></html>'
  17. >>> c = template.Context({'test':False, 'varvalue': 'Hello'})
  18. >>> t.render(c)
  19. '<html></html>'
  20. """

【source code】definition of template

  1. class Template:
  2. def __init__(self, template_string, origin=None, name=None, engine=None):
  3. # If Template is instantiated(illustrate) directly rather than from an Engine and
  4. # exactly one Django template engine is configured, use that engine.
  5. # This is required to preserve backwards-compatibility[兼容性] for direct use
  6. # e.g. Template('...').render(Context({...}))
  7. if engine is None:
  8. from .engine import Engine
  9. engine = Engine.get_default()
  10. if origin is None:
  11. origin = Origin(UNKNOWN_SOURCE)
  12. self.name = name
  13. self.origin = origin
  14. self.engine = engine
  15. self.source = template_string
  16. self.nodelist = self.compile_nodelist()
  17. def __iter__(self):
  18. for node in self.nodelist:
  19. yield from node
  20. def _render(self, context):
  21. return self.nodelist.render(context)
  22. def render(self, context):
  23. "Display stage -- can be called many times"
  24. with context.render_context.push_state(self):
  25. if context.template is None:
  26. with context.bind_template(self):
  27. context.template_name = self.name
  28. return self._render(context)
  29. else:
  30. return self._render(context)
  31. def compile_nodelist(self): # Nodelist is similar as array
  32. """
  33. Parse and compile the template source into a nodelist. If debug
  34. is True and an exception occurs during parsing, the exception is
  35. is annotated with contextual line information where it occurred in the
  36. template source.
  37. """
  38. if self.engine.debug:
  39. lexer = DebugLexer(self.source) # lexer---词法分析程序
  40. else:
  41. lexer = Lexer(self.source)
  42. tokens = lexer.tokenize()
  43. parser = Parser(
  44. tokens, self.engine.template_libraries, self.engine.template_builtins,
  45. self.origin,
  46. )
  47. try:
  48. return parser.parse()
  49. except Exception as e:
  50. if self.engine.debug:
  51. e.template_debug = self.get_exception_info(e, e.token)
  52. raise
  53. def get_exception_info(self, exception, token):
  54. """
  55. Return a dictionary containing contextual line information of where
  56. the exception occurred in the template. The following information is
  57. provided:
  58. message
  59. The message of the exception raised.
  60. source_lines
  61. The lines before, after, and including the line the exception
  62. occurred on.
  63. line
  64. The line number the exception occurred on.
  65. before, during, after
  66. The line the exception occurred on split into three parts:
  67. 1. The content before the token that raised the error.
  68. 2. The token that raised the error.
  69. 3. The content after the token that raised the error.
  70. total
  71. The number of lines in source_lines.
  72. top
  73. The line number where source_lines starts.
  74. bottom
  75. The line number where source_lines ends.
  76. start
  77. The start position of the token in the template source.
  78. end
  79. The end position of the token in the template source.
  80. """
  81. start, end = token.position
  82. context_lines = 10
  83. line = 0
  84. upto = 0
  85. source_lines = []
  86. before = during = after = ""
  87. for num, next in enumerate(linebreak_iter(self.source)):
  88. if start >= upto and end <= next:
  89. line = num
  90. before = escape(self.source[upto:start])
  91. during = escape(self.source[start:end])
  92. after = escape(self.source[end:next])
  93. source_lines.append((num, escape(self.source[upto:next])))
  94. upto = next
  95. total = len(source_lines)
  96. top = max(1, line - context_lines)
  97. bottom = min(total, line + 1 + context_lines)
  98. # In some rare cases exc_value.args can be empty or an invalid
  99. # string.
  100. try:
  101. message = str(exception.args[0])
  102. except (IndexError, UnicodeDecodeError):
  103. message = '(Could not get exception message)'
  104. return {
  105. 'message': message,
  106. 'source_lines': source_lines[top:bottom],
  107. 'before': before,
  108. 'during': during,
  109. 'after': after,
  110. 'top': top,
  111. 'bottom': bottom,
  112. 'total': total,
  113. 'line': line,
  114. 'name': self.origin.name,
  115. 'start': start,
  116. 'end': end,
  117. }

【technique】How to read specific source code

Day3---过滤器及模板标签 - 图1

【definition of Context】location: django/template/context.py

  1. class RenderContext(BaseContext):
  2. """
  3. A stack container for storing Template state.
  4. RenderContext simplifies the implementation【执行】 of template Nodes by providing a
  5. safe place to store state between invocations【d】 of a node's `render` method.
  6. The RenderContext also provides scoping rules that are more sensible for
  7. 'template local' variables. The render context stack is pushed before each
  8. template is rendered, creating a fresh scope with nothing in it. Name
  9. resolution fails if a variable is not found at the top of the RequestContext
  10. stack. Thus, variables are local to a specific template and don't affect the
  11. rendering of other templates as they would if they were stored in the normal
  12. template context.
  13. """
  14. template = None
  15. def __iter__(self):
  16. yield from self.dicts[-1]
  17. def __contains__(self, key):
  18. return key in self.dicts[-1]
  19. def get(self, key, otherwise=None):
  20. return self.dicts[-1].get(key, otherwise)
  21. def __getitem__(self, key):
  22. return self.dicts[-1][key]

【Context_processor】definition

  1. """
  2. A set of request processors that return dictionaries to be merged into a
  3. template context. Each function takes the request object as its only parameter
  4. and returns a dictionary to add to the context.
  5. These are referenced from the 'context_processors' option of the configuration
  6. of a DjangoTemplates backend and used by RequestContext.
  7. """
  8. import itertools
  9. from django.conf import settings
  10. from django.middleware.csrf import get_token
  11. from django.utils.functional import SimpleLazyObject, lazy
  12. def csrf(request):
  13. """
  14. Context processor that provides a CSRF token, or the string 'NOTPROVIDED' if
  15. it has not been provided by either a view decorator or the middleware
  16. """
  17. def _get_val():
  18. token = get_token(request)
  19. if token is None:
  20. # In order to be able to provide debugging info in the
  21. # case of misconfiguration, we use a sentinel[哨兵] value
  22. # instead of returning an empty dict.
  23. return 'NOTPROVIDED'
  24. else:
  25. return token
  26. return {'csrf_token': SimpleLazyObject(_get_val)}
  27. def debug(request):
  28. """
  29. Return context variables helpful for debugging.
  30. """
  31. context_extras = {}
  32. # 当前的项目处于DEBUG模式且请求的IP地址位于INTERNAL_IPS中
  33. if settings.DEBUG and request.META.get('REMOTE_ADDR') in settings.INTERNAL_IPS:
  34. # 用于标记当前处于DEBUG模式
  35. context_extras['debug'] = True
  36. from django.db import connections
  37. # 数据库的查询记录
  38. # Return a lazy reference that computes connection.queries on access,
  39. # to ensure it contains queries triggered after this function runs.
  40. context_extras['sql_queries'] = lazy(
  41. lambda: list(itertools.chain.from_iterable(connections[x].queries for x in connections)),
  42. list
  43. )
  44. # sql_queries是列表,记录一次清酒发生的SQL查询和每次查询的耗时
  45. return context_extras
  46. def i18n(request):
  47. from django.utils import translation
  48. return {
  49. 'LANGUAGES': settings.LANGUAGES,
  50. 'LANGUAGE_CODE': translation.get_language(),
  51. 'LANGUAGE_BIDI': translation.get_language_bidi(),
  52. }
  53. def tz(request):
  54. from django.utils import timezone
  55. return {'TIME_ZONE': timezone.get_current_timezone_name()}
  56. def static(request):
  57. """
  58. Add static-related context variables to the context.
  59. """
  60. return {'STATIC_URL': settings.STATIC_URL}
  61. def media(request):
  62. """
  63. Add media-related context variables to the context.
  64. """
  65. return {'MEDIA_URL': settings.MEDIA_URL}
  66. def request(request):
  67. return {'request': request}

【supplement】

backup

  1. <a href="#">{{name|cut:" "}}约么?</a>
  2. <a href="#">{{protagonist}}约</a>
  3. <a href="#">{{name}}去哪里?</a>
  4. <h1>这部分代码将要演示模板变量</h1>
  5. 这个变量是字符串对象:{{books_name}}<br>
  6. 这个变量是函数对象:{{hello}}<br>
  7. 这个变量是类方法对象:{{fruit.name}}<br>
  8. 这个变量是类对象,访问类对象的属性: {{fruit.say}}<br>
  9. 这个变量是列表对象:{{ list }}<br>
  10. 这个变量是列表对象,访问列表的元素{{list.1 }}<br>
  11. 这个变量是字典对象:{{dict}}<br>
  12. 这个变量是字典对象,访问字典的键{{dict.a }}<br>

【匿名用户】

  1. # PermWrapper[权限包装器] and PermLookupDict[权限查看字典] proxy the permissions system into objects that
  2. # the template system can understand.
  3. class PermLookupDict:
  4. def __init__(self, user, app_label):
  5. self.user, self.app_label = user, app_label
  6. def __repr__(self):
  7. return str(self.user.get_all_permissions())
  8. def __getitem__(self, perm_name):
  9. return self.user.has_perm("%s.%s" % (self.app_label, perm_name))
  10. def __iter__(self):
  11. # To fix 'item in perms.someapp' and __getitem__ interaction we need to
  12. # define __iter__. See #18979 for details.
  13. raise TypeError("PermLookupDict is not iterable.")
  14. def __bool__(self):
  15. return self.user.has_module_perms(self.app_label)
  16. class PermWrapper:
  17. def __init__(self, user):
  18. self.user = user
  19. def __getitem__(self, app_label):
  20. return PermLookupDict(self.user, app_label)
  21. def __iter__(self):
  22. # I am large, I contain multitudes.
  23. raise TypeError("PermWrapper is not iterable.")
  24. def __contains__(self, perm_name):
  25. """
  26. Lookup by "someapp" or "someapp.someperm" in perms.
  27. """
  28. if '.' not in perm_name:
  29. # The name refers to module.
  30. return bool(self[perm_name])
  31. app_label, perm_name = perm_name.split('.', 1)
  32. return self[app_label][perm_name]
  33. def auth(request):
  34. """
  35. Return context variables required by apps that use Django's authentication
  36. system.
  37. If there is no 'user' attribute in the request, use AnonymousUser (from
  38. django.contrib.auth).
  39. """
  40. if hasattr(request, 'user'):
  41. user = request.user
  42. else:
  43. from django.contrib.auth.models import AnonymousUser[匿名用户]
  44. user = AnonymousUser()
  45. return {
  46. 'user': user,
  47. 'perms': PermWrapper(user),
  48. }