09模板嵌套


技术交流QQ群:1027579432,欢迎你的加入!

本教程来源于B站杨仕航Django2.0开发视频教程,如需转载,必须注明来源!

1.模板嵌套

  • 观察上一讲中的前端模板文件blog_detail.html、blog_list.html、blog_with_type.html这三个文件,会发现三者中会有很多重复性的代码。因此,在blog文件目录下,创建base.html文件,将重复部分的代码添加进去,如下所示:
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <title>{% block title %}{% endblock %}</title>
        <meta charset="UTF-8">
    </head>
    <body>
        <div>
            <a href="{% url 'home' %}">
                <h3>个人博客网站</h3>
            </a>
        </div>
        <hr>
        {% block content %} {% endblock %}
    </body>
    </html>
    
  • blog_detail.html、blog_list.html、blog_with_type.html这三个文件如何引用base.html?删除blog_detail.html、blog_list.html、blog_with_type.html中的重复代码,然后引用base.html。修改后,各个文件的内容如下所示:
    {# blog_detail.html文件内容 #}
    {% extends 'base.html' %}
    
    {# 页面标题 #}
    {% block title %}
        {{ blog.title }}
    {% endblock %}
    
    {# 页面内容 #}
    {% block content %}
        <h3>{{ blog.title }}</h3>
        <p>作者: {{ blog.author }}</p>
        <p>发表日期: {{ blog.created_time|date:"Y-m-d G:i:s"}}</p>
        <p>分类:
            <a href="{% url 'blogs_with_type' blog.blog_type.pk%} ">
                {{ blog.blog_type }}
            </a>
        </p>
        <p>{{ blog.content }}</p>
    {% endblock %}
    
    <!-------------------------- 分割线 ------------------------------->
    {% extends 'base.html' %}
    
    {# blog_list.html文件内容 #}
    
    {# 页面标题 #}
    {% block title %}
        我的网站
    {% endblock %}
    
    {# 页面内容 #}
    {% block content %}
        <!-- 下一行中的blogs来自于views.py中的context['blogs'] = Blog.objects.all() -->
        {% for blog in blogs %}
        <!-- 下一行中的blog.title来自于models.py中的title = models.CharField(max_length=50) -->
            <a href="{% url 'blog_detail' blog.pk %}"><h3>{{ blog.title }}</h3></a>
            <p>{{ blog.content|truncatechars:30 }}</p>
        {% empty %}
            <p>--暂无博客,敬请期待--</p>
        {% endfor %}
        <p>一共有{{ blogs|length }}篇博客</p>
    {% endblock %}
    
    <!-------------------------- 分割线 ------------------------------->
    {% extends 'base.html' %}
    
    {# blogs_with_type.html文件内容 #}
    
    {# 页面标题 #}
    {% block title %}
        {{ blog_type.type_name }}
    {% endblock %}
    
    {# 页面内容 #}
    {% block content %}
        <!-- 下一行中的blogs来自于views.py中的context['blogs'] = Blog.objects.all() -->
        {% for blog in blogs %}
        <!-- 下一行中的blog.title来自于models.py中的title = models.CharField(max_length=50) -->
            <a href="{% url 'blog_detail' blog.pk %}"><h3>{{ blog.title }}</h3></a>
            <p>{{ blog.content|truncatechars:30 }}</p>
        {% empty %}
            <p>--暂无博客,敬请期待--</p>
        {% endfor %}
        <p>一共有{{ blogs|length }}篇博客</p>
    {% endblock %}
    

2.全局模板文件夹

  • 上一节中创建的公共模板文件base.html,只放在blog这个应用下的templates模板目录下。这违背了Django的封装性,不利于其他应用应用base.html这个公共的模板文件,不利于整个项目的迁移。因此,需要设置全局的模板文件夹。首先在整个mysite项目根目录下创建存放公共模板文件的templates文件夹,如下图所示。
    创建templates文件夹.png
  • 接着打开mysite文件夹下的全局设置文件settings.py,找到文件中的TEMPLATES变量,设置当中的DIRS 。DIRS添加如下的内容:
    'DIRS': [
            os.path.join(BASE_DIR, 'templates'),
        ],
    
  • 然后将blog文件目录下的templates文件夹下的公共模板文件base.html剪切到整个mysite项目根目录下创建存放公共模板文件的templates文件夹中。

3.模板设置文件建议

  • 如果某个应用app的模板文件只与这个应用有关,则存放在该某个应用的模板文件夹中;如果某个模板文件与整个项目project有关,则存放在整个项目的模板文件夹中。
  • 在整个mysite项目根目录下的templates文件夹中创建blog文件夹,接着将blog_detail.html、blog_list.html、blog_with_type.html这三个文件放到blog文件夹下。然后打开blog文件夹下的views.py文件,对该文件进行修改,添加blog文件路径,如下所示:
    from django.shortcuts import render_to_response, get_object_or_404
    from .models import Blog, BlogType
    # Create your views here.
    
    
    def blog_list(request):
        context = {}
        context['blogs'] = Blog.objects.all()
        return render_to_response('blog/blog_list.html', context)
    
    
    def blog_detail(request, blog_pk):
        context = {}
        context['blog'] = get_object_or_404(Blog, pk=blog_pk)
        return render_to_response('blog/blog_detail.html', context)
    
    
    def blogs_with_type(request, blog_type_pk):
        context = {}
        blog_type = get_object_or_404(BlogType, pk=blog_type_pk)
        context['blogs'] = Blog.objects.filter(blog_type=blog_type)
        context['blog_type'] = blog_type
        return render_to_response('blog/blogs_with_type.html', context)