python day51
Django之setting源码
django其实有两个配置文件
一个是暴露给用户可以自定义的配置文件,项目根目录下的settings.py。
一个是项目默认的配置文件,当用户不做任何配置的时候自动加载默认配置。
在配置文件中写入变量要注意全是大写
但是为什么当用户配置了就使用用户配置的而不配置的话就是使用默认的那?
这时候我们就需要导入它了
from django.conf import settings
通过查看源码得知
settings = LazySettings()
而LazySettings()是一个类,在这个类里
ENVIRONMENT_VARIABLE = "DJANGO_SETTINGS_MODULE"
class LazySettings(LazyObject):
def _setup(self, name=None):
# os.environ看成是一个全局大字典 ENVIRONMENT_VARIABLE就是 'day05.settings'
settings_module = os.environ.get(ENVIRONMENT_VARIABLE)
self._wrapped = Settings(settings_module) # Settings('day05.settings')
ENVIRONMENT_VARIABLE就是 'day05.settings’这个是怎么得出的哪?
通过查看manage.py我们发现是在manage.py中为那个字典设置一个键值对
if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "day05.settings")
再向下查看LazySettings()类我们发现
self._wrapped = Settings(settings_module) # Settings('day05.settings')
再查看Settings()
class Settings(object):
def __init__(self, settings_module): # 'day05.settings'
for setting in dir(global_settings): # 获取全局配置文件里面所有的变量名
if setting.isupper(): # 校验是否是纯大写
setattr(self, setting, getattr(global_settings, setting)) # 给Settings对象添加全局配置文件中所有的配置信息
self.SETTINGS_MODULE = settings_module # 'day05.settings'
mod = importlib.import_module(self.SETTINGS_MODULE)
# from day05 import settings # 导入暴露给用户的自定义配置文件
for setting in dir(mod):
if setting.isupper():
setting_value = getattr(mod, setting)
setattr(self, setting, setting_value)#这一步是如果全局中变量名存在则修改值而变量名不存在则添加值,以此来完成先导入全局,如果没有用户自定的则就按照全局默认的,而如果有则使用用户定义的。
模板层
模板语法之传参
传参的方式有两种
方式一:利用字典挨个传值,这一种方式传值精确,但当值很多的时候需要写大量的 k:v。
return render(request,'index.html',{'i':i,'f':f,'s':s})
方式二:简单粗暴 locals()将当前名称空间中所有的变量名全部传递给页面,但缺点是不够精确,可能会造成一定的资源浪费
return render(request,'index.html',locals())
如果传递函数名或类名的话会自动加括号调用并展示返回值,但是要注意!模板语法不支持额外的传参。
<p>{{obj}}</p>
<p>{{obj.get_self}}</p>
<p>{{obj_cls}}</p>
<p>{{ob_staticj}}</p>
<p>{{ob_staticj}}</p>
模板语法之获取值
django模板语法取值只能采用 句点符(.)
语法:索引 键都可以无限制的点点点
例:
<p>{{ d.hobby.3.username }}</p>
模板语法之过滤器
过滤器:将竖杆左侧的数据当做第一个参数
<p>统计长度{{s|length}}</p>
<p>加法运算{{i|add:10000}}</p>
<p>字符串拼接{{s|add:'hehe'}}</p>
<p>日期格式{{ctime|date:'Y年...'}}</p>
<p>默认值{{b|default:'哈哈'}}</p>
<p>默认值{{b1|default:'哈哈'}}</p>
<p>文件大小{{file_size|filesizeformat}}</p>
<p>截取文本(三个点也算){{s|truncatechars:6}}</p>
<p>截取文本(三个点不算) 空格截取{{s|truncatewords:3}}</p>
<p>告诉网页是安全的{{ h|safe }}</p>
告诉网页是安全的写法还有另外一种
后端
#导入模块
from django.utils.safestring import mark_safe
#后台告诉网页这个是安全的
ss = mark_safe('<h1>哟西</h1>')
前端
<p>{{ ss }}</p>
模板语法之标签
{{ }} 是变量相关
{% %} 是逻辑相关
流程控制
if…else
<p>标签(流程控制)</p>
{% if b %}
<p>有值</p>
{% else %}
<p>无值</p>
{% endif %}
for循环嵌套if
{% for foo in l %}
{% if forloop.first %}
<p>第一次</p>
{% elif forloop.last %}
<p>最后一次</p>
{% else %}
<p>{{ foo }}</p>
{% endif %}
{% empty %}
<p>for循环传入的数据为空</p>
{% endfor %}
{% empty %}是如果for没有值的话输出empty中的语句
了解
取别名可以将要…很多次的就写一次然后下次需要调用就直接使用别名
{% with d.username as username%}{# 取别名 #}
{{ username }}
{{ d.password }}
{% endwith %}
自定义过滤器、标签、inclusion_tag
自定义过滤器就类似于python里面的自定义函数。
自定义过滤器使用步骤:
1,在应用下创建一个名字必须叫"templatetags"文件夹
2,在上述文件夹内创建一个名字任意的py文件
3, 在该py文件内固定先书写以下两句话
from django import template
register = template.Library()
使用案例:
from django import template
register = template.Library()
#自定义过滤器
@register.filter(name='myfilter')
def index(a, b):#要注意这个过滤器只能接收两个参数
#简单加法
return a + b
#自定义标签
@register.simple_tag(name='mysimple')
def func1(a, b, c, d):
return '%s-%s|%s_%s' % (a, b, c, d)
# 自定义inclusion_tag
# inclusion_tag
# 当某个区域需要反复使用并且数据不是固定的
@register.inclusion_tag('login.html',name='my_inclusion_tag')
def func2(n):
l = []
for i in range(1,n):
l.append('第%s页' %i)
return
在页面上的使用方式
#自定义过滤器
{% load mytag %}
{{ i| myfilter:666 }}
#自定义标签
{% mysimple 1 'json' 222 'hehe' %}
# inclusion_tag
{% my_inclusion_tag 10 %}
模板的导入
模板的导入类似于后端到模块 想要什么局部页面直接导入即可。
{% include 'myform.html' %}
模板的继承
要完成模板的继承需要先先使用block划定区域
母版
{% block css %}
{% endblock %}
{% block content %}
{% endblock %}
{% block js %}
{% endblock %}
一般来说我们在母版中划分3块~X块的大区域
主要有 单独的css,以及js。目的是为了让子版具有独立的css js等 增加扩展性。而html中的则是根据你想需求划分多少块不定。
子版
{% extends 'home.html' %}
{% block 区域名称 %}
{% endblock %}
而子版还能继续使用母版的划定区域
{{ block.super }}