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 就是绝对路径的前面固定的那一部分
TEMPLATES = [
{
...
'DIRS': [os.path.join(BASE_DIR,'templates')],
...
},
]
然后继续老操作,新建 urls.py
写入:
#coding:utf-8
from django.urls import path
from .views import Index
urlpatterns = [
path('', Index.as_view(), name='index')
]
修改 template 下的 urls.py 将 app 中的 urls 引入进来
from django.contrib import admin
from django.urls import path,include
from app import urls as app_urls
urlpatterns = [
path('admin/', admin.site.urls),
path('', include(app_urls))
]
然后修改视图:views.py,使用了自带的 render
#coding:utf-8
from django.shortcuts import render
from django.views.generic import View
class Index(View):
TEMPLATE = 'index.html'
def get(self, request):
return render(request, self.TEMPLATE)
最后在 templates 文件夹(新建)下创建一个index.html ,随便写点东西
然后在 terminal 中写入 python manage.py runserver 即成功
数据传递
在 views.py 中的 render 方法中使用大括号的形式传入想要传递的值
def get(self, request):
return render(request, self.TEMPLATE, {'name': 'demonlb'})
然后在 index.html 中使用 大括号的形式进行承接(类似 vue)
<div>your name :{{name}}</div>
3-2 内置标签与静态配置
变量与标签
- 变量是用双大括号包裹的,比如我们从后端拿到的数据
- 内置标签类型使用 {% %} 大括号 左右
内置标签
第三条中的 args 是用来设置传递的参数
for标签模板
静态文件配置
- 项目根目录创建 ‘static’ 与 ‘template’ 文件夹同级
- STATICFILES_DIRS = (os.path.join(BASE_DIR, ‘static’))
静态文件
css js img
2021-10-9
3-3 静态文件配置与内置标签代码演示
基础架构搭建
继续在 3.2 的基础上使用 lesson4-template 来操作
新建一个 static 文件夹
然后在 settings.py 中对这个 static 进行定义
STATICFILES_DIRS = (os.path.join(BASE_DIR, 'static'),)
forloop 相关代码展示
然后写一个 0-9 的循环
定义列表,把 name 和 array 放进去
def get(self, request, name):
# return render(request, self.TEMPLATE, {'name': 'demonlb'})
# 定义一个列表
data = {}
data['name'] = name
data['array'] = range(10)
# return render(request, self.TEMPLATE, {'name': name})
# 用上面的替换下面的
return render(request, self.TEMPLATE, data)
然后把新的 array 放进去
<ul>
{% for item in array %}
<li>
{{item}}
</li>
{% endfor %}
</ul>
就会有 0-10 的
结合 forloop 的一些使用
<ul>
{% for item in array %}
<li>
<!-- forloop.counter0 是从 0 开始计算, counter是从 1 开始计算,revcounter 是从最大值开始递减 -->
{{item}} --- {{ forloop.counter0 }} --- {{ forloop.counter }} --- {{ forloop.revcounter }} --- {{ forloop.revcounter0 }}
{% if forloop.first %}
is first
{% elif forloop.last %}
is last
{% endif %}
</li>
{% empty %}
<li> is empty</li>
{% endfor %}
</ul>
url 跳转代码展示
<a href="{% url 'index' 'anything' %}">go back</a>
点击就会跳转到 anything
引入 static 文件
首先在 static 中新建一个 index.css 里面随便写点东西
然后在 index.html 中引入
{% load static %}
...
<link rel="stylesheet" href="{% static 'index.css' %}">
...
定义基础的 HTML 模板,然后继承
使用 block 语法定义基本的模板:head,title,css,html,JavaScript 一共五个部分
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}{% endblock %}</title>
{% block css_style %}
{% endblock %}
{% endblock %}
</head>
<body>
{% block content %}
{% endblock %}
{% block js_script %}
{% endblock %}
</body>
</html>
使用:在引入的 html 中的头部写入 即可
{% extends 'base.html' %}
进一步使用
{% extends 'base.html' %}
{% load static %}
{% block css_style %}
<link rel="stylesheet" href="{% static 'index.css' %}">
{% endblock %}
{% block title %}
test
{% endblock %}
{% block content%}
<body>
<div>123</div>
<div>your name :{{name}}</div>
<ul>
{% for item in array %}
<li>
{{item}} --- {{ forloop.counter0 }} --- {{ forloop.counter }} --- {{ forloop.revcounter }} --- {{ forloop.revcounter0 }}
{% if forloop.first %}
is first
{% elif forloop.last %}
is last
{% endif %}
</li>
{% empty %}
<li> is empty</li>
{% endfor %}
</ul>
<a href="{% url 'index' 'anything' %}">go back</a>
</body>
{% endblock %}
2021-10-12
3-4 内置过滤器自定义过滤器
过滤器的用处
用于在html模版中,对于渲染过来的数据进行二次操作使用
过滤器其实就是用来处理这些数据的模版引擎中使用的函数
(在 html 中使用后端 Python 的函数)
常用过滤器
自定义过滤器
在Django服务器端编写函数,在模版中可以直接调用的过滤器函数
操作:定义自定义函数规则
- 在应用下创建 templatetags 文件夹
- 在文件夹下创建 myfilter.py
举例:
3-5 内置过滤器
列举几种内置的过滤器
<label>add: </label>{{count|add:10}} <br />
<label>date: </label>{{time|date:"Y-m-d H:i:s"}} <br />
<label>cut-str: </label>{{cut_str|cut:"-"}} <br />
<label>capfirst: </label>{{cut_str|capfirst}} <br />
<label>default: </label>{{default|default:"空列表"}} <br />
自定义过滤器
1.在 app 下新建 templatetags 文件夹,并在里面创建 init.py 和 myfilter.py
2.在 myfilter.py 中写入一个自定的filter:乘法
#coding:utf-8
from django import template
register = template.Library()
@register.filter
def test(value, args):
return value * args
3.使用:在 index.html 的顶部写入以下代码,test为方法名,后面跟参数
{% load myfilter %}
...
{% comment %} 使用自定义filter {% endcomment %}
<label>custom: </label>{{count|test:10}} <br />
2021-10-13
3-6 jinja2与mako
jinja2
◆Jinja2是一套模仿Django模版的模版引擎 ,由Flask开发者开发,它的使用场景和Django的模版非常相似。它速度快,被广泛使用。
◆Jinja2提倡让Html设计者和后端Python开发工作分离
jinja2 一些常用过滤器
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
base_jinja2.py
#coding: utf-8
from jinja2 import Environment
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import reverse
def virtual_environment(**options):
env = Environment(**options)
env.globals.update({
'static': staticfiles_storage.url,
'url': reverse
})
return env
然后修改基础的 settings 中的 TEMPLATES
将 django 引擎更换为 jinja2 引擎
TEMPLATES = [
{
'BACKEND': 'django.template.backends.jinja2.Jinja2',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
...
},
]
然后创建 templates 文件夹,对应这个 dirs
然后导入设置的虚拟环境
这里的路径一定要对应统一
TEMPLATES = [
{
...
'OPTIONS': {
...
'environment': 'app.base_jinja2.virtual_environment'
},
},
]
使用
在 views.py 中定义使用
from django.shortcuts import render
# Create your views here.
def test(request):
data = {'name': 'robinluo', 'age': 18}
return render(request, 'test.html', data)
test.html
{% extends 'base.html' %}
{% block content %}
{{name|title}}
{% endblock content %}
自定义 filter
在 app 中定义一个 myfilter.py
并书写自定义的 filter
#coding:utf-8
# 定义自定义 filter
def test(value, args):
return value * args
使用:
和 django 不同的是,需要使用括号传值的形式
{% extends 'base.html' %}
{% block content %}
...
{{age|test(2)}}
{% endblock content %}
传入静态文件:例如CSS
创建 /static/index.css
然后在 index.html 中引入
{% block css_style %}
<link rel="stylesheet" href="/static/index.css" />
{% endblock css_style %}
2021-10-18
3-8 mako的配置与使用方法
mako配置
创建 mako_project
/test/django-learning/lesson6-mako_test/mako_project
创建 app 下载 mako
django-admin startproject mako_project
然后进入mako_project/
python manage.py startapp app
pip install mako
基本使用
在 mako_project/app/base_render.py 中写入
#coding:utf-8
from mako.lookup import TemplateLookup
from django.template import RequestContext
from django.conf import settings
from django.template.context import Context
from django.http import HttpResponse
def render_to_response(request, template, content=None):
context_instance = RequestContext(request)
path = settings.TEMPLATES[0]['DIRS'][0]
lookup = TemplateLookup(
directories=[path],
output_encoding='utf-8',
input_encoding='utf-8'
)
mako_template = lookup.get_template(template)
if not content:
content = {}
if context_instance:
context_instance.update(content)
else:
context_instance = Context(content)
data = {}
for d in context_instance:
data.update(d)
# 创建 csrf-token
data['csrf_token'] = '<input type="hidden" name="csrfmiddlewaretoken" value="{0}" />'.format(request.META['CSRF_COOKIE'])
return HttpResponse(mako_template.render(**data))
然后分别修改一些文件views.py
#coding:utf-8
from re import TEMPLATE
from django.views.generic import View
from .base_render import render_to_response
class Test(View):
TEMPLATE = 'test.html'
def get(self, request):
return render_to_response(request, self.TEMPLATE)
urls.py
from django.contrib import admin
from django.urls import path
from app.views import Test
urlpatterns = [
path('admin/', admin.site.urls),
path('test/', Test.as_view())
]
mako的使用
然后修改一下 view.py 中的 get 方法
加一条数据 data
...
def get(self, request):
data = {'name': 'demonlb', 'age': 30}
return render_to_response(request, self.TEMPLATE, content=data)
然后在 test.html 中就可以直接用 name age 了
${name} ${age}
mako 模板最大的好处就是可以直接使用 Python 语法来书写内容
比如这样
<%!
from django.conf import settings
%>
${settings.TEMPLATES[0]['DIRS'][0]}
写一些其他内容
<%!
from django.conf import settings
%>
## 获取值
${settings.TEMPLATES[0]['DIRS'][0]}
## for 循环
%for i in range(20):
<input type="text" value="${i}"></input>
%endfor
## 定义函数并使用
<%
def name():
return 'my name is robinluo'
%>
<br>
<input type="text" name="username" value="${name()}"/>
然后定义 base.html 作为基础模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>${self.title()}</title>
</head>
<body>
${self.content()}
</body>
</html>
<%def name="title()"%></%def>
<%def name="js()"%></%def>
<%def name="css()"%></%def>
<%def name="content()"%>
${self.main()}
</%def>
<%def name="main()"%></%def>
然后在 test.html 中使用它
<%inherit file="base.html" />
<%def name="main()">
<%!
from django.conf import settings
%>
## 获取值
${settings.TEMPLATES[0]['DIRS'][0]}
## for 循环
%for i in range(20):
<input type="text" value="${i}"></input>
%endfor
## 定义函数并使用
<%
def name():
return 'my name is robinluo'
%>
<br>
<input type="text" name="username" value="${name()}"/>
</%def>
使用模板继承
<%def name="js()">
<script src="http://cdn.bootcss.com/jquery/2.2.0/jquery.js"></script>
</%def>
还有引用css html传值等等
2021-10-19/20
3-9 项目练习-Django模板实践与枚举学习、消息屏蔽
枚举类型
新建 constant.py
通过 python shell 来操作
可以正确拿到数据
再继续定义一系列数据
# coding:utf-8
from enum import Enum
class MessageType(Enum):
info = 'info'
warning = 'warning'
error = 'error'
danger = 'danger'
MessageType.info.label = '信息'
MessageType.warning.label = '警告'
MessageType.error.label = '错误'
MessageType.danger.label = '危险'
MessageType.info.color = 'green'
MessageType.warning.color = 'orange'
MessageType.error.color = 'gray'
MessageType.danger.color = 'red'
然后在视图中处理这些数据
在 views.py 中
输出data的不同类型值,其中根据错误的类型进行独特的判断
...
from .constant import MessageType
class TestOne(View):
TEMPLATE = 'three.html'
def get(self, request, message_type):
data = {}
try:
message_type_obj = MessageType[message_type]
except Exception as e:
data['error'] = '没有这个消息类型'.format(e)
return render(request, self.TEMPLATE, data)
message = request.GET.get('message','')
if not message:
data['error'] = '消息不可为空'
return render(request, self.TEMPLATE, data)
data['message'] = message
data['message_type'] = message_type_obj
return render(request, self.TEMPLATE, data)
然后继续写模板
将数据渲染过来
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=s, initial-scale=1.0">
<title>Document</title>
</head>
<body>
{% if error %}
<h3>error: {{error}}</h3>
{% else %}
{% comment %} 没有 error 就把消息message传进来 {% endcomment %}
<span style="color:{{message_type.color}}">{{message}}</span>
{% endif %}
</body>
</html>
当键入 info1 因为 没有这个内容,所以出现 error,命中模板的 h3 标签
键入这个:info?message=demonlb
成功渲染出内容来
继续修改模板,加一个 label
{% if error %}
<h3>error: {{error}}</h3>
{% else %}
{% comment %} 没有 error 就把消息message传进来 {% endcomment %}
<label style="color:{{message_type.color}}">{{message_type.label}}</label>
<span>{{message}}</span>
{% endif %}
效果:
然后给它做一个信息过滤
安装 jieba
在 custom.py 中写入
@register.filter(name='deep_check_message')
def deep_check(value):
cut_message = jieba.lcut(value)
new_message = []
for word in cut_message:
if word in SensitiveWord:
new_message.append('*')
else:
new_message.append(word)
if new_message:
return ''.join(new_message)
return value