文章详情页 您现在的位置是:网站首页>文章详情
关于django后端渲染的笔记
Jeyrce.Lu
发表于:2019年4月16日 02:01
分类:【Python】
3615次阅读
为什么不在views中写html
太坑
views写html标签(业务和显示的耦合性太高)
显示提取到index.txt,业务中直接读取成字符串(.txt,不会联想)
将标签写到html,显示和业务分离成功,会联想
随着项目逐渐增大,html越来越多,那么html放在哪里?
django说templtes
提供一个便利?
def index_view(request):
return render_me('templates/sencod.html')
def render_me(path):
with open(path, 'rb') as fr:
content = fr.read()
return HttpResponse(content)能不能不写呢?可以
在settings中的TEMPLATES
'DIRS': [os.path.join(BASE_DIR, 'templates')]
获得settings中的DIRS
def index_view(request):
return render_me('asdasd')
def render_me(path):
from settings import TEMPLATES
import os
dirs = TEMPLATES[0].get('DIRS')
filepath=''
for dir in dirs:
if os.path.exists(os.path.join(dir,path)):
filepath=os.path.join(dir,path)
if not filepath:
raise Exception('templte does not exist')
with open(filepath, 'rb') as fr:
content = fr.read()
return HttpResponse(content)django.shortcut render
render(request,'sencod.html')
Template
模板的渲染流程
def index_view(request):
content = 'hello:{{name}}' # 模板字符串
from django.template import Template
t = Template(content) # 创建模板
from django.template import Context
c = Context({'name':'张三'}) # 准备数据
render_string = t.render(c) # 渲染
return HttpResponse(render_string)将显示和业务分离
# 原来是Template类的实例支持模板标签
def index_view(request):
with open('templates/sencod.html') as fr:
content = fr.read() # content = '<font color="red">hello:{{name}}</font>' # 模板字符串
from django.template import Template
t = Template(content) # 创建模板
from django.template import Context
c = Context({'name':'张三'}) # 准备数据
render_string = t.render(c) # 渲染
return HttpResponse(render_string)字典
def index_view(request):
with open('templates/sencod.html') as fr:
content = fr.read() # content = '<font color="red">hello:{{name}}</font>' # 模板字符串
# content = html # 模板字符串
from django.template import Template
t = Template(content) # 创建模板
from django.template import Context
c = Context({'users':users}) # 准备数据
render_string = t.render(c) # 渲染
return HttpResponse(render_string)render的简化版的源代码
def render_me(path,data={}):
from settings import TEMPLATES
import os
dirs = TEMPLATES[0].get('DIRS')
filepath=''
for dir in dirs:
if os.path.exists(os.path.join(dir,path)):
filepath=os.path.join(dir,path)
if not filepath:
raise Exception('templte does not exist')
with open(filepath, 'rb') as fr:
content = fr.read() #模板字符串
from django.template import Template
t = Template(content) # 创建模板
from django.template import Context
c = Context(data) # 准备数据
render_string = t.render(c) # 渲染
return HttpResponse(render_string)模板渲染的步骤
获得原始字符串
创建模板
准备数据
渲染,获得渲染之后的字符串
返回HttpResponse对象
def index_view(request):
raw_content = 'hello :{{name}}' #准备原始字符串
t = Template(raw_content) # 准备模板
c = Context({'name':'张三'}) # 准备数据
render_string = t.render(c) # 渲染,并获得渲染的字符串
return HttpResponse(render_string)loader
t = loader.get_template('模板路径')
def index_view(request):
t = loader.get_template('index.html') #<class 'django.template.backends.django.Template'>
render_string = t.render({'name':'张三'})
return HttpResponse(render_string)模板渲染的原理设计的对象
django.template Template
django.templte Context
django.shortcut loader
settings分析
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',#渲染引擎
'DIRS': [os.path.join(BASE_DIR, 'templates')], # html模板存放的未知
'APP_DIRS': True, # 可以在模块下寻找模板
'OPTIONS': {
'context_processors': [ # 全局上下文
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]APP_DIRS:True(模板就可以直接写在模块中templates中),完全的模块化了。
APP_DIRS:False (寻找模板的时候就不会在模块下找了)
INSTALL_APPS作用
数据迁移的时候使用
寻找模块下的模板时候使用
DTL
django template lanague
如果一个变量找不到,DTL不会报错,而是显示空白
{{}}
变量 (任意的对象)
.作用
访问字典值
render(request,'post.html',{'user':{'name':'张三','age':10}})
# html 姓名:{{ user.name }},年龄:{{ user.age }}访问对象属性
render(request,'post.html',{'today':datetime.datetime.today()})
# html {{ today.year }}-{{ today.month }}-{{ today.day }}访问对象的方法(不能有参数)
render(request,'post.html',{'duanzi':'hello world'})
# html {{ duanzi.capitalize }}访问列表(不能使负数索引)
render(request,'post.html',{'items':['asd','s']})
# html {{items.1}}随便给模板传入一个对象 . 先按照字典查user['age'],在按照属性查user.age,再按照方法查user.age(),按照列表索引查user[age]
在django中访问不存在东西,是不会报错的,就是空白字符
{% %}
if
{% if items != None %} # 记得有空格
itmes不是空
{% endif %}
{% if items %}items不是空{% else %}items是空{% endif %}
{% if gender == '男' %}男生{% elif gender == '女' %}女生{% else %}未知{% endif %}模板中写嵌套非常难阅读,业务应该放到业务层(views层)做判断,模板中做的是简单的显示,隐藏。
支持and or not
for 携带forloop
{% for user in users %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}
{% for user in users %}
<tr style="color: {% if forloop.first %}red{% elif forloop.last %}cadetblue{% endif %}">
<td>{{ forloop.counter }}</td>
<td>{{ user.name }}</td>
<td>{{ user.age }}</td>
</tr>
{% endfor %}forloop
counter,counter0,revcounter,last,first
对于列表 reversed
empty
{% for item in items reversed%}
{{ item }}<br>
{% empty %}当前没有数据
{% endfor %}for不支持break,continue(所以复杂业务都在views中处理好)
多循环
{% for user in users %}
{% for k,v in user.items %}
{{ forloop.parentloop.counter }} --{{forloop.counter }}--{{ k }}--{{ v }}<br>
{% endfor %}
{% endfor %}comment 注释{##}
{% comment %}
{% for user in users %}
{% for k,v in user.items %}
{{ forloop.parentloop.counter }} --{{forloop.counter }}--{{ k }}--{{ v }}<br>
{% endfor %}
{% endfor %}
{% endcomment %}转义
所有的数据纯字符串,不进行解析
django将模板中的数据都进行了自动转义,防止 跨站脚本攻击(Cross Site Scripting,XSS)
关闭转义
{% autoescape off %}
{{ user.name }}
{% endautoescape %}csrf_token(跨站请求伪造)其实起不了多大的防护作用。
csrftoken 在cookie中(唯一的表示浏览器),1年过期
csrfmiddlewaretoken(每请求一次,就变)
d={csrftoken:csrfmiddlewaretoken,csrftoken:csrfmiddlewaretoken}
# 请求头自动携带cookie(csrftoken)
# form表单提交csrfmiddlewaretoken
d.get(csrftoken) == form表单提交csrfmiddlewaretoken
# 原理 ,自己写一个csrf_token
# {%csrf_token%} =====> <input type='hidden' name='csrfmiddlewaretoken' value='tqVHekuJNnlOwwSTAX8oIRepkxwQQNoPdmbOfWrPgs8GzjkLW6vHhMGOEa5OLVMg' />
d={csrftoken:'y7OyWpLPesgdcyjraSxiqdACSfu2xq8rJdixKZDVZWKm3B6XMUJt9YFbJGj2X3uf'}
# cookie会在请求头自动携带y7OyWpLPesgdcyjraSxiqdACSfu2xq8rJdixKZDVZWKm3B6XMUJt9YFbJGj2X3uf
d.get('EHRWgmZQl8wXNzd4N2035ndAFUz0qtnRhwUTMq0ygUkUrydHESWs6RPBH2mYH82m') # ==y7OyWpLPesgdcyjraSxiqdACSfu2xq8rJdixKZDVZWKm3B6XMUJt9YFbJGj2X3ufdjango模板中不支持传参
过滤器来解决模板中不支持传参问题
过滤器在任何标签中都能使用
url逆向解析
reverse('order:myorder')
通过,模块的命名空间:函数名 (找到处理函数的真实地址)
函数中处理
get传递参数 ?参数
resetful传参数 捕获
url = reverse('order:myorder',args=(10,))+"?time=2017-11-11"模板中
<a href="{%url 'order:myorder' 100 %}?time=20-10-10">我的订单</a>模板继承
extends 继承html
include 将其他的html包含进来
block 挖坑,填坑
上下文
Context
RequestContext
有一些共同函数,需要一些共同的行为
#coding=utf-8
from django.http.response import HttpResponse
def user_processor(request): # 函数
print request
#User.objects.get(id = request.GET.get('uid'))
return {'name':'张三'} # 字典
def index1_view(request):
from django.template import Template,RequestContext
t = Template('{{name}}:数据')
render_string = t.render(RequestContext(request,dict_=None,processors=(user_processor,)))
return HttpResponse(render_string)
def index2_view(request):
t = Template('{{name}}:数据')
render_string = t.render(RequestContext(request, dict_=None,processors=(user_processor,)))
return HttpResponse(render_string)
def index3_view(request):
from django.template import Template, RequestContext
t = Template('{{name}}:数据')
render_string = t.render(RequestContext(request, dict_=None,processors=(user_processor,)))
return HttpResponse(render_string)
def index4_view(request):
return HttpResponse('index4')
def index5_view(request):
return HttpResponse('index5')render(request,)
全局上下文(类似全局变量和局部变量)
# 配置在Templates中的context_processors
def age_processor(request):
return {'age':'asdasdadads'}
TEMPLATES = [{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
'request.age_context_process.age_processor'
],
},
},]格式
def 函数名(request):
#插叙数据库
return {'':''}static标签
专门访问静态文件夹的东西
{%load staticfiles%}{%static 'a.jpg'%}过滤器
last
first
length
length_is:2
truncatechars:30
safe 关闭转义
divisibleby:2
{% for c in content %}
<li style="color: {% if forloop.counter|divisibleby:2 %}mediumvioletred{% else %}fuchsia{% endif %}">{{ c }}</li>
{% endfor %}自定义过滤器
mark_down
pip install markdown
创建过滤器的步骤
在模块中创建一个包,templatetags
在templatetags包中创建一个文件(随便起)
在这个创建的文件中写代码
from django.template import Library regitser = Library() @register.filter def md(value): # 默认传入的 import markdown return markdown.markdown(value)
{% load 创建的文件 %}
在template中就可以使用了
自定义截取
# {{content|s:'1,20'}}
@register.filter
def s(value,args):
# ''
start ,end = args.split(',')
content = value.encode('utf-8').decode('utf-8')
return content[int(start):int(end)]自定义标签
@register.simple_tag() def u(value): return reverse(value)
版权声明 本文属于本站 原创作品,文章版权归本站及作者所有,请尊重作者的创作成果,转载、引用自觉附上本文永久地址: http://blog.lujianxin.com/x/art/1v4r1rrv1syt
下一篇:时光中,追逐与回首
猜你喜欢
文章评论区
作者名片
- 作者昵称:Jeyrce.Lu
- 原创文章:61篇
- 转载文章:3篇
- 加入本站:2396天
作者其他文章
站长推荐
友情链接
站点信息
- 运行天数:2397天
- 累计访问:164169人次
- 今日访问:0人次
- 原创文章:69篇
- 转载文章:4篇
- 微信公众号:第一时间获取更新信息
