模板介绍
DTL(Django Template Language)是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。
DTL与普通HTML的区别
DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。
渲染模板
渲染模板有多种方式,以下是两种常用的方式:
from django.shortcuts import render, HttpResponse
from django.template.loader import render_to_string
# Create your views here.
# 第一种渲染方式
def m_index(request):
html = render_to_string('index_music.html')
return HttpResponse(html)
# 第二种渲染方式
def m_pop(request):
return render(request, 'pop_music.html')
- render_to_string:
- 找到模板,然后将模板编译后渲染成Python的字符串格式;
- 最后再通过HttpResponse类包装成一个HttpResponse对象返回。
- render:
- 直接将模板渲染成字符串,并包装成HttpResponse对象一步到位完成;
- render实际是接受了
render_to_string
的返回值。def render(request, template_name, context=None, content_type=None, status=None, using=None):
"""
Return a HttpResponse whose content is filled with the result of calling
django.template.loader.render_to_string() with the passed arguments.
"""
content = loader.render_to_string(template_name, context, request, using=using)
return HttpResponse(content, content_type, status)
模板路径配置
在项目的settings.py
文件中,TEMPLATES
项包含了模板目录的配置,模板上下文的配置等。
模板路径相关配置如下:
- DIRS:这个列表中存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板时,会在这个列表的路径中查找模板。
- APP_DIRS:默认为True,若在
INSTALLED_APPS
项中添加项目的app名字,且在该app目录下创建了模板目录及模板文件,那么在渲染模板时,会在该目录下进行查找。
渲染模板时,模板文件的查找顺序:list.html
- 先在
DIRS
这个列表中依次查找路径下有没有这个模板,如果有,就返回; - 如果DIRS列表中的路径没有找到该文件,且
APP_DIRS
值为True时,那么会先检查当前这个视图所处的app是否已经安装(INSTALLED_APPS),如果已安装,会先在当前app下的templates
文件夹中查找模板; - 如果也没有找到,那么会在其他已经安装了的app中查找;
- 如果所有路径下都没有找到,那么会抛出一个
TemplateDoesNotExist
的异常。
查找优先级:DIRS -> INSTALLED_APPS
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'template_demo', # 项目app名字
]
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
# 'DIRS': [os.path.join(BASE_DIR, 'templates')]
'DIRS': [r"D:\Project_Django\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',
],
},
},
]
模板变量
变量需要通过视图函数渲染,视图函数在使用render或者render_to_string渲染时,可以传递一个 context
参数,该参数需要是一个字典类型。
"""views.py"""
def profile(request):
return render(request, 'profile.html', context={'username': 'Rick'})
class Person(object):
def __init__(self, username):
self.username = username
def guys(request):
name = Person("唐三")
content = {
'person': name, # 此person是一个对象
'persons': [
'小舞',
'奥斯卡',
'荣荣'
]
}
return render(request, "guys.html", context=content)
"""profile和guys,HTML模板中的变量,接收返回值"""
<h2>Hello,{{ username }}</h2>
<h2>Hello,{{ person.username }}</h2>
<h2>Hello,{{ persons.0 }}</h2>
模板中的变量支持点(.)的形式,比如person.username。使用该方式时,模板是按照以下进行解析的:
- 如果person是一个字典,那么就会查找这个字典的key(即username)对应的值;
- 如果person是一个对象,那么就会查找这个对象的username属性,或者是username这个方法;
- 如果出现的是
persons.1
,会判断persons是否是一个列表或元组,或者任意可以通过下标访问的对象。如果是,就取其第1个值;如果不是,获取到的则是一个空的字符串。