文章详情页 您现在的位置是:网站首页>文章详情
关于django后端渲染的笔记
        
             Jeyrce.Lu
        发表于:2019年4月16日 02:01
        分类:【Python】
        3607次阅读
        
        Jeyrce.Lu
        发表于:2019年4月16日 02:01
        分类:【Python】
        3607次阅读
    
为什么不在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篇
- 加入本站:2390天
作者其他文章
站长推荐
友情链接
站点信息
- 运行天数:2391天
- 累计访问:164169人次
- 今日访问:0人次
- 原创文章:69篇
- 转载文章:4篇
- 微信公众号:第一时间获取更新信息
 
    