2021-9-29

3-1 模版的配置绑定与渲染

Template介绍,配置,与 View 的绑定

模板可以动态生成HTML网页,包括部分HTML代码和一些特殊的语法

Template配置方法

  • 一般 template 模板存在 “template” 目录中
  • 通过在项目 Settings 的 templates 的 DIRS 列表中添加对应的路径即可,如:
    • os.path.join(BASE_DIR, ‘templates’)

Template与视图的绑定

  • 通过 from django.shortcuts import render 模块
  • return render(request, template_path, {k:v}),字典中的 key 和 value 就是要向前端渲染出来的数据

Template展示渲染的数据

在 html 中以{{}} 为表示,在双大括号中传入视图中的数据

实操

基本搭建

在 django-learning 下创建 lesson4-template
然后创建项目 django-admin startproject template
cd template 后创建应用app: python manage.py startapp app

vscode进入 lesson4-template/template,创建一个 templates 文件夹
然后进入 template/settings.py 中找到 TEMPLATES.DIRS
这里的 BASE_DIR 就是绝对路径的前面固定的那一部分

  1. TEMPLATES = [
  2. {
  3. ...
  4. 'DIRS': [os.path.join(BASE_DIR,'templates')],
  5. ...
  6. },
  7. ]

然后继续老操作,新建 urls.py
写入:

  1. #coding:utf-8
  2. from django.urls import path
  3. from .views import Index
  4. urlpatterns = [
  5. path('', Index.as_view(), name='index')
  6. ]

修改 template 下的 urls.py 将 app 中的 urls 引入进来

  1. from django.contrib import admin
  2. from django.urls import path,include
  3. from app import urls as app_urls
  4. urlpatterns = [
  5. path('admin/', admin.site.urls),
  6. path('', include(app_urls))
  7. ]

然后修改视图:views.py,使用了自带的 render

  1. #coding:utf-8
  2. from django.shortcuts import render
  3. from django.views.generic import View
  4. class Index(View):
  5. TEMPLATE = 'index.html'
  6. def get(self, request):
  7. return render(request, self.TEMPLATE)

最后在 templates 文件夹(新建)下创建一个index.html ,随便写点东西
然后在 terminal 中写入 python manage.py runserver 即成功

数据传递

在 views.py 中的 render 方法中使用大括号的形式传入想要传递的值

  1. def get(self, request):
  2. return render(request, self.TEMPLATE, {'name': 'demonlb'})

然后在 index.html 中使用 大括号的形式进行承接(类似 vue)

  1. <div>your name :{{name}}</div>

image.png

3-2 内置标签与静态配置

变量与标签

  • 变量是用双大括号包裹的,比如我们从后端拿到的数据
  • 内置标签类型使用 {% %} 大括号 左右

内置标签

image.png
第三条中的 args 是用来设置传递的参数

for标签模板

image.png

静态文件配置

  • 项目根目录创建 ‘static’ 与 ‘template’ 文件夹同级
  • STATICFILES_DIRS = (os.path.join(BASE_DIR, ‘static’))

静态文件

css js img

2021-10-9

3-3 静态文件配置与内置标签代码演示

基础架构搭建

继续在 3.2 的基础上使用 lesson4-template 来操作
新建一个 static 文件夹
image.png
然后在 settings.py 中对这个 static 进行定义

  1. STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)

forloop 相关代码展示

然后写一个 0-9 的循环
定义列表,把 name 和 array 放进去

  1. def get(self, request, name):
  2. # return render(request, self.TEMPLATE, {'name': 'demonlb'})
  3. # 定义一个列表
  4. data = {}
  5. data['name'] = name
  6. data['array'] = range(10)
  7. # return render(request, self.TEMPLATE, {'name': name})
  8. # 用上面的替换下面的
  9. return render(request, self.TEMPLATE, data)

然后把新的 array 放进去

  1. <ul>
  2. {% for item in array %}
  3. <li>
  4. {{item}}
  5. </li>
  6. {% endfor %}
  7. </ul>

就会有 0-10 的

  • 渲染出来

    结合 forloop 的一些使用

    1. <ul>
    2. {% for item in array %}
    3. <li>
    4. <!-- forloop.counter0 是从 0 开始计算, counter是从 1 开始计算,revcounter 是从最大值开始递减 -->
    5. {{item}} --- {{ forloop.counter0 }} --- {{ forloop.counter }} --- {{ forloop.revcounter }} --- {{ forloop.revcounter0 }}
    6. {% if forloop.first %}
    7. is first
    8. {% elif forloop.last %}
    9. is last
    10. {% endif %}
    11. </li>
    12. {% empty %}
    13. <li> is empty</li>
    14. {% endfor %}
    15. </ul>

    image.png

    url 跳转代码展示

    1. <a href="{% url 'index' 'anything' %}">go back</a>

    点击就会跳转到 anything
    image.png

    引入 static 文件

    image.png
    首先在 static 中新建一个 index.css 里面随便写点东西
    然后在 index.html 中引入
    image.png

    1. {% load static %}
    2. ...
    3. <link rel="stylesheet" href="{% static 'index.css' %}">
    4. ...

    定义基础的 HTML 模板,然后继承

    使用 block 语法定义基本的模板:head,title,css,html,JavaScript 一共五个部分

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. {% block head %}
    5. <meta charset="UTF-8">
    6. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    7. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    8. <title>{% block title %}{% endblock %}</title>
    9. {% block css_style %}
    10. {% endblock %}
    11. {% endblock %}
    12. </head>
    13. <body>
    14. {% block content %}
    15. {% endblock %}
    16. {% block js_script %}
    17. {% endblock %}
    18. </body>
    19. </html>

    使用:在引入的 html 中的头部写入 即可

    1. {% extends 'base.html' %}

    进一步使用

    1. {% extends 'base.html' %}
    2. {% load static %}
    3. {% block css_style %}
    4. <link rel="stylesheet" href="{% static 'index.css' %}">
    5. {% endblock %}
    6. {% block title %}
    7. test
    8. {% endblock %}
    9. {% block content%}
    10. <body>
    11. <div>123</div>
    12. <div>your name :{{name}}</div>
    13. <ul>
    14. {% for item in array %}
    15. <li>
    16. {{item}} --- {{ forloop.counter0 }} --- {{ forloop.counter }} --- {{ forloop.revcounter }} --- {{ forloop.revcounter0 }}
    17. {% if forloop.first %}
    18. is first
    19. {% elif forloop.last %}
    20. is last
    21. {% endif %}
    22. </li>
    23. {% empty %}
    24. <li> is empty</li>
    25. {% endfor %}
    26. </ul>
    27. <a href="{% url 'index' 'anything' %}">go back</a>
    28. </body>
    29. {% endblock %}

    2021-10-12

    3-4 内置过滤器自定义过滤器

    过滤器的用处

    用于在html模版中,对于渲染过来的数据进行二次操作使用
    过滤器其实就是用来处理这些数据的模版引擎中使用的函数
    (在 html 中使用后端 Python 的函数)

    常用过滤器

    image.png
    image.png
    等等,除了以上这些写好的,还可以自定义函数->自定义过滤器

    自定义过滤器

    在Django服务器端编写函数,在模版中可以直接调用的过滤器函数

    操作:定义自定义函数规则

    • 在应用下创建 templatetags 文件夹
    • 在文件夹下创建 myfilter.py

    举例:
    image.png

    3-5 内置过滤器

    列举几种内置的过滤器
    image.png

    1. <label>add: </label>{{count|add:10}} <br />
    2. <label>date: </label>{{time|date:"Y-m-d H:i:s"}} <br />
    3. <label>cut-str: </label>{{cut_str|cut:"-"}} <br />
    4. <label>capfirst: </label>{{cut_str|capfirst}} <br />
    5. <label>default: </label>{{default|default:"空列表"}} <br />

    自定义过滤器

    1.在 app 下新建 templatetags 文件夹,并在里面创建 init.py 和 myfilter.py
    2.在 myfilter.py 中写入一个自定的filter:乘法

    1. #coding:utf-8
    2. from django import template
    3. register = template.Library()
    4. @register.filter
    5. def test(value, args):
    6. return value * args

    3.使用:在 index.html 的顶部写入以下代码,test为方法名,后面跟参数

    1. {% load myfilter %}
    2. ...
    3. {% comment %} 使用自定义filter {% endcomment %}
    4. <label>custom: </label>{{count|test:10}} <br />

    2021-10-13

    3-6 jinja2与mako

    其他常用模板介绍

    jinja2

    ◆Jinja2是一套模仿Django模版的模版引擎 ,由Flask开发者开发,它的使用场景和Django的模版非常相似。它速度快,被广泛使用。
    ◆Jinja2提倡让Html设计者和后端Python开发工作分离

    jinja2 一些常用过滤器

    image.png

    Mako

    ◆mako模板算是Python里面比较出色的一个模板了,它宣称有比Jinja2更快的解析速度,已经更多的语法支持
    ◆最大的特点在于,它可以允许你在Html中随意书写Python代码

    3-7 jinja2配置与使用方法

    1.创建lesson5-jinja_test: /django-learning/lesson5-jinja_test
    2.然后创建 project
    django-admin startproject jinja_test
    3.下载 jinja 依赖
    pip install jinja2
    4.然后进入创建好的 jinja 文件夹下:/django-learning/lesson5-jinja_test/jinja_test
    创建应用:python manage.py startapp app
    5.创建基础jinja文件:base_jinja2.py
    image.png

    base_jinja2.py

    1. #coding: utf-8
    2. from jinja2 import Environment
    3. from django.contrib.staticfiles.storage import staticfiles_storage
    4. from django.urls import reverse
    5. def virtual_environment(**options):
    6. env = Environment(**options)
    7. env.globals.update({
    8. 'static': staticfiles_storage.url,
    9. 'url': reverse
    10. })
    11. return env

    然后修改基础的 settings 中的 TEMPLATES
    将 django 引擎更换为 jinja2 引擎

    1. TEMPLATES = [
    2. {
    3. 'BACKEND': 'django.template.backends.jinja2.Jinja2',
    4. 'DIRS': [os.path.join(BASE_DIR, 'templates')],
    5. ...
    6. },
    7. ]

    然后创建 templates 文件夹,对应这个 dirs

    然后导入设置的虚拟环境
    这里的路径一定要对应统一

    1. TEMPLATES = [
    2. {
    3. ...
    4. 'OPTIONS': {
    5. ...
    6. 'environment': 'app.base_jinja2.virtual_environment'
    7. },
    8. },
    9. ]

    使用

    在 views.py 中定义使用

    1. from django.shortcuts import render
    2. # Create your views here.
    3. def test(request):
    4. data = {'name': 'robinluo', 'age': 18}
    5. return render(request, 'test.html', data)

    test.html

    1. {% extends 'base.html' %}
    2. {% block content %}
    3. {{name|title}}
    4. {% endblock content %}

    自定义 filter

    在 app 中定义一个 myfilter.py
    并书写自定义的 filter

    1. #coding:utf-8
    2. # 定义自定义 filter
    3. def test(value, args):
    4. return value * args

    使用:
    和 django 不同的是,需要使用括号传值的形式

    1. {% extends 'base.html' %}
    2. {% block content %}
    3. ...
    4. {{age|test(2)}}
    5. {% endblock content %}

    传入静态文件:例如CSS

    创建 /static/index.css
    然后在 index.html 中引入

    1. {% block css_style %}
    2. <link rel="stylesheet" href="/static/index.css" />
    3. {% endblock css_style %}

    2021-10-18

    3-8 mako的配置与使用方法

    mako配置

    创建 mako_project
    /test/django-learning/lesson6-mako_test/mako_project
    创建 app 下载 mako

    1. django-admin startproject mako_project
    2. 然后进入mako_project/
    3. python manage.py startapp app
    4. pip install mako

    基本使用
    在 mako_project/app/base_render.py 中写入

    1. #coding:utf-8
    2. from mako.lookup import TemplateLookup
    3. from django.template import RequestContext
    4. from django.conf import settings
    5. from django.template.context import Context
    6. from django.http import HttpResponse
    7. def render_to_response(request, template, content=None):
    8. context_instance = RequestContext(request)
    9. path = settings.TEMPLATES[0]['DIRS'][0]
    10. lookup = TemplateLookup(
    11. directories=[path],
    12. output_encoding='utf-8',
    13. input_encoding='utf-8'
    14. )
    15. mako_template = lookup.get_template(template)
    16. if not content:
    17. content = {}
    18. if context_instance:
    19. context_instance.update(content)
    20. else:
    21. context_instance = Context(content)
    22. data = {}
    23. for d in context_instance:
    24. data.update(d)
    25. # 创建 csrf-token
    26. data['csrf_token'] = '<input type="hidden" name="csrfmiddlewaretoken" value="{0}" />'.format(request.META['CSRF_COOKIE'])
    27. return HttpResponse(mako_template.render(**data))

    然后分别修改一些文件views.py

    1. #coding:utf-8
    2. from re import TEMPLATE
    3. from django.views.generic import View
    4. from .base_render import render_to_response
    5. class Test(View):
    6. TEMPLATE = 'test.html'
    7. def get(self, request):
    8. return render_to_response(request, self.TEMPLATE)

    urls.py

    1. from django.contrib import admin
    2. from django.urls import path
    3. from app.views import Test
    4. urlpatterns = [
    5. path('admin/', admin.site.urls),
    6. path('test/', Test.as_view())
    7. ]

    成功!

    mako的使用

    然后修改一下 view.py 中的 get 方法
    加一条数据 data

    1. ...
    2. def get(self, request):
    3. data = {'name': 'demonlb', 'age': 30}
    4. return render_to_response(request, self.TEMPLATE, content=data)

    然后在 test.html 中就可以直接用 name age 了

    1. ${name} ${age}

    mako 模板最大的好处就是可以直接使用 Python 语法来书写内容
    比如这样

    1. <%!
    2. from django.conf import settings
    3. %>
    4. ${settings.TEMPLATES[0]['DIRS'][0]}

    image.png
    写一些其他内容

    1. <%!
    2. from django.conf import settings
    3. %>
    4. ## 获取值
    5. ${settings.TEMPLATES[0]['DIRS'][0]}
    6. ## for 循环
    7. %for i in range(20):
    8. <input type="text" value="${i}"></input>
    9. %endfor
    10. ## 定义函数并使用
    11. <%
    12. def name():
    13. return 'my name is robinluo'
    14. %>
    15. <br>
    16. <input type="text" name="username" value="${name()}"/>

    image.png
    然后定义 base.html 作为基础模板

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
    7. <title>${self.title()}</title>
    8. </head>
    9. <body>
    10. ${self.content()}
    11. </body>
    12. </html>
    13. <%def name="title()"%></%def>
    14. <%def name="js()"%></%def>
    15. <%def name="css()"%></%def>
    16. <%def name="content()"%>
    17. ${self.main()}
    18. </%def>
    19. <%def name="main()"%></%def>

    然后在 test.html 中使用它

    1. <%inherit file="base.html" />
    2. <%def name="main()">
    3. <%!
    4. from django.conf import settings
    5. %>
    6. ## 获取值
    7. ${settings.TEMPLATES[0]['DIRS'][0]}
    8. ## for 循环
    9. %for i in range(20):
    10. <input type="text" value="${i}"></input>
    11. %endfor
    12. ## 定义函数并使用
    13. <%
    14. def name():
    15. return 'my name is robinluo'
    16. %>
    17. <br>
    18. <input type="text" name="username" value="${name()}"/>
    19. </%def>

    使用模板继承

    1. <%def name="js()">
    2. <script src="http://cdn.bootcss.com/jquery/2.2.0/jquery.js"></script>
    3. </%def>

    还有引用css html传值等等

    2021-10-19/20

    3-9 项目练习-Django模板实践与枚举学习、消息屏蔽

    枚举类型
    image.png
    新建 constant.py
    image.png
    通过 python shell 来操作
    image.png
    可以正确拿到数据
    再继续定义一系列数据

    1. # coding:utf-8
    2. from enum import Enum
    3. class MessageType(Enum):
    4. info = 'info'
    5. warning = 'warning'
    6. error = 'error'
    7. danger = 'danger'
    8. MessageType.info.label = '信息'
    9. MessageType.warning.label = '警告'
    10. MessageType.error.label = '错误'
    11. MessageType.danger.label = '危险'
    12. MessageType.info.color = 'green'
    13. MessageType.warning.color = 'orange'
    14. MessageType.error.color = 'gray'
    15. MessageType.danger.color = 'red'

    然后在视图中处理这些数据
    在 views.py 中
    输出data的不同类型值,其中根据错误的类型进行独特的判断

    1. ...
    2. from .constant import MessageType
    3. class TestOne(View):
    4. TEMPLATE = 'three.html'
    5. def get(self, request, message_type):
    6. data = {}
    7. try:
    8. message_type_obj = MessageType[message_type]
    9. except Exception as e:
    10. data['error'] = '没有这个消息类型'.format(e)
    11. return render(request, self.TEMPLATE, data)
    12. message = request.GET.get('message','')
    13. if not message:
    14. data['error'] = '消息不可为空'
    15. return render(request, self.TEMPLATE, data)
    16. data['message'] = message
    17. data['message_type'] = message_type_obj
    18. return render(request, self.TEMPLATE, data)

    然后继续写模板
    将数据渲染过来

    1. <!DOCTYPE html>
    2. <html lang="en">
    3. <head>
    4. <meta charset="UTF-8">
    5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
    6. <meta name="viewport" content="width=s, initial-scale=1.0">
    7. <title>Document</title>
    8. </head>
    9. <body>
    10. {% if error %}
    11. <h3>error: {{error}}</h3>
    12. {% else %}
    13. {% comment %} 没有 error 就把消息message传进来 {% endcomment %}
    14. <span style="color:{{message_type.color}}">{{message}}</span>
    15. {% endif %}
    16. </body>
    17. </html>

    当键入 info1 因为 没有这个内容,所以出现 error,命中模板的 h3 标签
    image.png
    键入这个:info?message=demonlb
    成功渲染出内容来
    image.png

    继续修改模板,加一个 label

    1. {% if error %}
    2. <h3>error: {{error}}</h3>
    3. {% else %}
    4. {% comment %} 没有 error 就把消息message传进来 {% endcomment %}
    5. <label style="color:{{message_type.color}}">{{message_type.label}}</label>
    6. <span>{{message}}</span>
    7. {% endif %}

    效果:
    image.png

    然后给它做一个信息过滤
    安装 jieba
    在 custom.py 中写入

    1. @register.filter(name='deep_check_message')
    2. def deep_check(value):
    3. cut_message = jieba.lcut(value)
    4. new_message = []
    5. for word in cut_message:
    6. if word in SensitiveWord:
    7. new_message.append('*')
    8. else:
    9. new_message.append(word)
    10. if new_message:
    11. return ''.join(new_message)
    12. return value