模板介绍

DTL(Django Template Language)是Django自带的模板语言。当然也可以配置Django支持Jinja2等其他模板引擎,但是作为Django内置的模板语言,和Django可以达到无缝衔接而不会产生一些不兼容的情况。

DTL与普通HTML的区别

DTL模板是一种带有特殊语法的HTML文件,这个HTML文件可以被Django编译,可以传递参数进去,实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端。

渲染模板

渲染模板有多种方式,以下是两种常用的方式:

  1. from django.shortcuts import render, HttpResponse
  2. from django.template.loader import render_to_string
  3. # Create your views here.
  4. # 第一种渲染方式
  5. def m_index(request):
  6. html = render_to_string('index_music.html')
  7. return HttpResponse(html)
  8. # 第二种渲染方式
  9. def m_pop(request):
  10. return render(request, 'pop_music.html')
  • render_to_string:
    • 找到模板,然后将模板编译后渲染成Python的字符串格式;
    • 最后再通过HttpResponse类包装成一个HttpResponse对象返回。
  • render:
    • 直接将模板渲染成字符串,并包装成HttpResponse对象一步到位完成;
    • render实际是接受了 render_to_string 的返回值。
      1. def render(request, template_name, context=None, content_type=None, status=None, using=None):
      2. """
      3. Return a HttpResponse whose content is filled with the result of calling
      4. django.template.loader.render_to_string() with the passed arguments.
      5. """
      6. content = loader.render_to_string(template_name, context, request, using=using)
      7. return HttpResponse(content, content_type, status)

      模板路径配置

      在项目的 settings.py 文件中, TEMPLATES 项包含了模板目录的配置,模板上下文的配置等。

模板路径相关配置如下:

  1. DIRS:这个列表中存放所有的模板路径,以后在视图中使用render或者render_to_string渲染模板时,会在这个列表的路径中查找模板。
  2. APP_DIRS:默认为True,若在INSTALLED_APPS 项中添加项目的app名字,且在该app目录下创建了模板目录及模板文件,那么在渲染模板时,会在该目录下进行查找。

渲染模板时,模板文件的查找顺序:list.html

  1. 先在 DIRS 这个列表中依次查找路径下有没有这个模板,如果有,就返回;
  2. 如果DIRS列表中的路径没有找到该文件,且 APP_DIRS 值为True时,那么会先检查当前这个视图所处的app是否已经安装(INSTALLED_APPS),如果已安装,会先在当前app下的 templates 文件夹中查找模板;
  3. 如果也没有找到,那么会在其他已经安装了的app中查找;
  4. 如果所有路径下都没有找到,那么会抛出一个 TemplateDoesNotExist 的异常。

查找优先级:DIRS -> INSTALLED_APPS

  1. INSTALLED_APPS = [
  2. 'django.contrib.admin',
  3. 'django.contrib.auth',
  4. 'django.contrib.contenttypes',
  5. 'django.contrib.sessions',
  6. 'django.contrib.messages',
  7. 'django.contrib.staticfiles',
  8. 'template_demo', # 项目app名字
  9. ]
  10. TEMPLATES = [
  11. {
  12. 'BACKEND': 'django.template.backends.django.DjangoTemplates',
  13. # 'DIRS': [os.path.join(BASE_DIR, 'templates')]
  14. 'DIRS': [r"D:\Project_Django\templates"] # 指定其他路径
  15. ,
  16. 'APP_DIRS': True,
  17. 'OPTIONS': {
  18. 'context_processors': [
  19. 'django.template.context_processors.debug',
  20. 'django.template.context_processors.request',
  21. 'django.contrib.auth.context_processors.auth',
  22. 'django.contrib.messages.context_processors.messages',
  23. ],
  24. },
  25. },
  26. ]

模板变量

变量需要通过视图函数渲染,视图函数在使用render或者render_to_string渲染时,可以传递一个 context 参数,该参数需要是一个字典类型。

  1. """views.py"""
  2. def profile(request):
  3. return render(request, 'profile.html', context={'username': 'Rick'})
  4. class Person(object):
  5. def __init__(self, username):
  6. self.username = username
  7. def guys(request):
  8. name = Person("唐三")
  9. content = {
  10. 'person': name, # 此person是一个对象
  11. 'persons': [
  12. '小舞',
  13. '奥斯卡',
  14. '荣荣'
  15. ]
  16. }
  17. return render(request, "guys.html", context=content)
  18. """profile和guys,HTML模板中的变量,接收返回值"""
  19. <h2>Hello,{{ username }}</h2>
  20. <h2>Hello,{{ person.username }}</h2>
  21. <h2>Hello,{{ persons.0 }}</h2>

模板中的变量支持点(.)的形式,比如person.username。使用该方式时,模板是按照以下进行解析的:

  1. 如果person是一个字典,那么就会查找这个字典的key(即username)对应的值;
  2. 如果person是一个对象,那么就会查找这个对象的username属性,或者是username这个方法;
  3. 如果出现的是 persons.1 ,会判断persons是否是一个列表或元组,或者任意可以通过下标访问的对象。如果是,就取其第1个值;如果不是,获取到的则是一个空的字符串。