我爱Django框架之Django模板的简单应用(你想要的这都有!!!)

模板介绍和渲染模板

Django模板的介绍

       •我们在前面使用Django时,视图函数返回的只是文本,而在实际开发应用中其实很少这样使用,而是返回带有样式的HTML代码,这样可以让浏览器渲染出美观的页面,供用户使用
       •DTL即Django Template Language,是指Django框架自带的模板语言,使用一种带有特殊语法的HTML文件,可以被Django编译,还可以传递参数、实现数据动态化。在编译完成后,生成一个普通的HTML文件,然后发送给客户端进行渲染显示
       •Django框架同时也支持配置Jinja2等其他模板引擎,但是DTL作为Django内置的模板语言,DTL可以和Django达到无缝衔接、不会产生不兼容的情况,前提是不采用前后端分离的开发模式

模板渲染

       •模板渲染的有多种不同方式,主要包括以下两种:

              •django.template.loader.render_to_string
              根据配置的模板路径和传入的模板名称寻找模板,然后将模板编译后渲染成HTML字符串,再通过HttpResponse类包装成一个HttpResponse对象返回
              •django.shortcuts.render
              这是一种更加简便的方式,直接将模板渲染成字符串并包装成HttpResponse对象一步完成。render()方法其实也是调用的render_to_string()方法,只不过又进行了一次封装,因此使用起来也更加方便

       •第一种方式测试如下:
       •先通过命令django-admin startproject django_template新建项目django_template,并进入项目目录,然后通过命令python manage.py startapp book创建名为book的app

       •首先在项目目录下新建模板目录templates,在模板目录下新建book.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>Django模板测试</p>
</body>
</html>

       •然后在项目目录下的settings.py中定义模板路径如下:

 import os
 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',
            ],
        },
    },
]

注意:一定要导入os模块

       •book app的views.py如下:

from django.http import HttpResponse
from django.template.loader import render_to_string


def index(request): # 第一种方法
    html = render_to_string('book.html')
    return HttpResponse(html)

       •book目录下新建urls.py如下:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index)
]

       •项目目录下的urls.py文件:

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('admin/', admin.site.urls),
    path('book/', include('book.urls'))
]

注意:

       •按照以上顺序即可成功的渲染模板,注意在settings.py文件中一定要导入os模块

       •Django框架中支持自定义模板路径,不一定是templates目录、可以自定义模板路径,只要在DIRS列表中添加路径即可

       •网页显示:
在这里插入图片描述
       •从网页结果显示可以看出来 模板已经被成功渲染

       •第二种方式测试如下:
       •book app的views.py如下:

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string


def index(request):  # 第一种方法
    html = render_to_string('index.html')
    return HttpResponse(html)


def book(request):  # 第二种方法
    return render(request, 'books.html')

       •在模板目录下新建books.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>Django模板测试2</p>
</body>
</html>

       •book目录下的urls.py文件如下:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index),
    path('books/', views.book)
]

       •网页显示如下:
在这里插入图片描述
       •由上面可以看出,第二种方法更加方便,我们以后在日常开发中会使用更多

       •其实还有一种方式render_to_response(),这与render()方法类似,只是增加了warnings.warn()方法,其源码如下:

def render_to_response(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.
    """
    warnings.warn(
        'render_to_response() is deprecated in favor of render(). It has the '
        'same signature except that it also requires a request.',
        RemovedInDjango30Warning, stacklevel=2,
    )
    content = loader.render_to_string(template_name, context, using=using)
    return HttpResponse(content, content_type, status)

       •render()方法源码如下:

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中配置模板路径,给DIRS变量添加具体路径到列表即可
       •以上配置是在TEMPLATES变量中进行的,这个配置包含了模板引擎、模板查找路径、模板上下文等

       •模板文件的路径可以在两个地方配置:
              •DIRS
              DIRS是一个列表,在这个列表中可以存放所有的模板路径,在视图中使用render或者render_to_string渲染模板的时候,会在这个列表的路径中查找模板的具体位置进行渲染
              •APP_DIRS
              默认为True,设置为True后,会在项目目录下的settings.py文件中的INSTALLED_APPS中已经注册的APP下的templates目录中查找模板
              如果要使用APP_DIRS这种配置方法,只需要在项目目录下的settings.py文件中的INSTALLED_APPS列表中添加相应的app名字进行注册

模板查找顺序

       •比如现在有一个模板index.html,并且要在视图函数中将其作为参数进行渲染,查找此模板的顺序如下:
              首先会在DIRS列表中依次查找路径下有没有该模板,如果有则返回
              如果DIRS列表中所有的路径都没有找到,那么会先检查当前这个视图所处的app是否已经在INSTALLED_APPS中注册,如果已经注册,那么就先在当前这个app下的templates文件夹中查找模板
              如果还是没有找到,那么会在其他已经注册了的app中查找模板
              如果所有路径下都没有找到,会抛出TemplateDoesNotExist异常

测试如下:
       •book app的views.py如下:

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string


def index(request):
    html = render_to_string('index.html')
    return HttpResponse(html)


def book_list(request):
    return render(request, 'booklist.html')


def book_detail(request):
    return render(request, 'bookdetail.html')

       •book app的urls.py定义路由如下:

from django.urls import path

from . import views

urlpatterns = [
    path('', views.index),
    path('booklist/', views.book_list),
    path('bookdetail/', views.book_detail),
]

       •在项目目录下settings.py注册app如下:

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'book'
]

       •在book app下新建templates目录,新建booklist.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>莫问前程</p>
</body>
</html>

       •项目目录下的templates目录新建bookdetail.html文件如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>但行好事</p>
</body>
</html>

       •网页测试如下:
在这里插入图片描述
       •在访问http://127.0.0.1:8000/book/booklist时查找booklist.html先在项目DIRS指定的模板目录即项目模板目录中查找,查找到直接渲染
       •访问http://127.0.0.1:8000/book/bookdetail时,bookdetail.html在项目模板目录中未查找到,则到INSTALLED_APPS目录中查找,查找到后进行渲染

DTL模板变量

       •模板中可以包含变量,以保证Django框架在渲染模板的时候可以传递变量对应的值进行替换,以实现动态显示
       •模板变量的命名规范和Python类似,包括只能是阿拉伯数字和英文字符以及下划线的组合、不能出现标点符号等特殊字符等
       •变量需要通过视图函数传递到模板进行渲染,和Flask框架中的用法类似,视图函数在调用render或者render_to_string时指定context参数实现参数传递,context参数类型为字典

       •测试如下:
       •book app下的views.py如下:

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string


def index(request):
    html = render_to_string('index.html')
    return HttpResponse(html)


def book_list(request):
    return render(request, 'booklist.html', context={'name': 'Python从入门到入土'})


def book_detail(request):
    return render(request, 'bookdetail.html')

       •templates/booklist.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>图书列表</p>
    <p>图书名称:{{ name }}</p>
</body>
</html>

       •网页显示如下:
在这里插入图片描述
       •测试各种变量进行传参
       •book app下的views.py如下:

from django.http import HttpResponse
from django.shortcuts import render
from django.template.loader import render_to_string


def index(request):
    html = render_to_string('index.html')
    return HttpResponse(html)


class Person(object):
    def __init__(self, username):
        self.username = username


def book_list(request):
    context = {
        'username': 'Ycx',
        'books': ['Python', 'Java', 'PHP'],
        'authors': ('Jack', 'Tom', 'Cbh'),
        'info': {
            'name': 'Django'
        },
        'person': Person('CH')
    }
    return render(request, 'booklist.html', context=context)


def book_detail(request):
    return render(request, 'bookdetail.html')

       •templates/booklist.html如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <p>用户名:{{ username }}</p>
    <p>图书列表</p>
    <p>{{ books.0 }}</p>
    <p>{{ books.1 }}</p>
    <p>{{ books.2 }}</p>
    <p>作家列表</p>
    <p>{{ authors.0 }}</p>
    <p>{{ authors.1 }}</p>
    <p>{{ authors.2 }}</p>
    <p>信息</p>
    <p>{{ info.name }}</p>
    <p></p>
    <p>{{ person.username }}</p>
    <p>{{ person.email }}</p>
</body>
</html>

       •网页显示:
在这里插入图片描述
       •由上可得:
              •如果取不到值会不显示,也不会报错,这是因为未匹配到时会返回空字符串。

              •如果参数是列表、元组、字典等类型,直接使用点号.调用的,模板是按照以下方式进行解析的
              •如果变量是一个列表或元组,会根据数字索引查找相应的值
              •如果变量是一个字典,那么就会查找key对应的值
              •如果变量是一个对象,那么就会查找这个对象的相应属性或者方法

       •不能通过中括号[]的形式访问字典和列表中的值,比如 info[‘name’]books[1] 是获取不到值的

注意

       •使用点号.语法获取对象值的时候,可以获取这个对象的属性,如果这个对象是一个字典,也可以获取这个字典的值,所以在视图函数中给字典添加key的时候,命名不能和字典中的一些属性重复
       • 比如items是字典自带的方法,那么如果给这个字典添加一个items作为key,以后就不能再通过items来访问这个字典的键值对

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值