5.2 模板继承与静态文件


文档摘要

5.2 模板继承与静态文件 本节摘要:当页面从三个涨到三十个,复制粘贴的 HTML 会反噬项目。本节讲模板继承体系:base 骨架开块、子模板填块、局部模板 include 复用;随后理顺两条文件线——开发写的静态文件与用户上传的媒体文件,各自的配置、引用与部署期归宿。 继承:骨架开块,子页填空 先写全站骨架 base 模板: 子模板只声明继承并填块: 规则很干脆:extends 必须是子模板第一个标签;一个子模板只能继承一个父模板,但父模板可以再继承祖父,形成多层链。子模板想在父块内容基础上追加而非替换,用 block.super: 继承树全景 继承树全景 include 与 extends 的分工:extends 解决"页面级骨架复用",include 解决"局部组件复用"。

5.2 模板继承与静态文件

本节摘要:当页面从三个涨到三十个,复制粘贴的 HTML 会反噬项目。本节讲模板继承体系:base 骨架开块、子模板填块、局部模板 include 复用;随后理顺两条文件线——开发写的静态文件与用户上传的媒体文件,各自的配置、引用与部署期归宿。

继承:骨架开块,子页填空

先写全站骨架 base 模板:

{# base.html 全站骨架 #} <!DOCTYPE html> <html lang="zh"> <head> <title>{% block title %}墨迹博客{% endblock %}</title> {% load static %} <link rel="stylesheet" href="{% static 'css/site.css' %}"> </head> <body> <nav>导航栏(全站一致)</nav> <main> {% block content %}默认内容{% endblock %} </main> <aside> {% block sidebar %}默认侧栏{% endblock %} </aside> </body> </html>

子模板只声明继承并填块:

{# blog/list.html 文章列表 #} {% extends "base.html" %} {% block title %}最新文章 - 墨迹博客{% endblock %} {% block content %} {% for a in articles %} <article> <h3><a href="{% url 'blog:article-detail' a.pk %}">{{ a.title }}</a></h3> <p>{{ a.body|truncatechars:120 }}</p> </article> {% empty %} <p>这里还空着。</p> {% endfor %} {% endblock %}

规则很干脆:extends 必须是子模板第一个标签;一个子模板只能继承一个父模板,但父模板可以再继承祖父,形成多层链。子模板想在父块内容基础上追加而非替换,用 block.super:

{% block title %}{{ block.super }} - 分类页{% endblock %}

继承树全景

继承树全景

include 与 extends 的分工:extends 解决"页面级骨架复用",include 解决"局部组件复用"。评论列表既出现在详情页又出现在个人主页,就抽成局部模板。命名约定以下划线开头(下划线开头表示它不是完整页面),被 include 时可传参。include 会拿到当前上下文,需要隔离时用 only 参数收口。

静态文件:第一条线

样式表、脚本、图标这些"开发期写死、随代码部署"的文件走 staticfiles 体系:

{% load static %} <link rel="stylesheet" href="{% static 'css/site.css' %}"> <script src="{% static 'js/main.js' %}"></script> <img src="{% static 'img/logo.png' %}" alt="墨迹博客">

static 标签的产出不是简单的路径拼接:它叠加了应用内静态目录、项目级静态目录,并在第 10 章的部署形态下指向收集后的统一目录。要点有三:

  1. 永远用 static 标签引用,不手写相对路径——页面 URL 层级一深,相对路径全崩。
  2. 静态目录可分层:应用自己的静态资源放应用目录下(带应用名子目录防冲突),全站的放项目级目录。
  3. 部署时执行收集命令,把散落各处的静态文件汇总到统一目录,交给 Nginx 直接服务——第 10 章部署清单里的一项。

开发环境下 staticfiles 应用自动提供静态服务;生产环境它默认不再服务静态文件,这不是坑,是分工:生产上静态文件属于反向代理的工作,应用进程不该耗在传文件上。

媒体文件:第二条线

用户上传的配图、附件是另一种文件:内容随用户行为产生,不随代码部署。两条线必须分开:

# 配置示意 MEDIA_URL = "/media/" MEDIA_ROOT = BASE_DIR / "media"

模型字段用 ImageField 或 FileField 接收上传,属性访问时框架会拼接媒体地址:

class Article(models.Model): cover = models.ImageField("封面图", upload_to="covers/", blank=True)

模板里 {{ article.cover.url }} 输出完整地址。开发环境要在根路由把媒体目录挂给开发服务器;生产环境同样交由 Nginx 服务,且上传目录要有大小与类型限制——第 12 章安全清单会回头收紧。

💡 两条线的判断口诀:代码仓库该不该管它?该,就是静态;不该(每个环境内容不同),就是媒体。分不清时的混乱代价是备份策略与部署脚本一起乱。

模板体系的长期维护账

模板继承树搭好后,真正的考验在半年后的维护期:页面改版需求来了,是该改块的内容还是加新块?新页面该继承到哪一层?这里给两条从墨迹博客实践中沉淀的判断。第一,块的粒度跟着页面的变化频率走:全站半年不变的头部导航放骨架模板里直接写死,各页微调的区域才抽成块——过早抽象出的块,改版时反而要在父模板和子模板间来回对照,比写死更费神。第二,继承深度控制在三层以内:骨架、中间布局、具体页面,再深一层,模板调试就要人肉模拟渲染顺序,效率陡降。当某个页面发现自己在第三层还大量覆写父级的块,说明它不适合这棵树,宁可单独给它一张平铺模板。模板体系的健康标准不是复用率最高,而是任何人能在十秒内判断出改某个视觉元素要动哪个文件。

本节要点回顾

  • 继承三规则:extends 置顶、单继承可多层、block.super 追加不覆盖。
  • extends 管页面骨架,include 管局部组件,两层复用各司其职。
  • 静态文件永远用 static 标签,部署时收集、交给 Nginx。
  • 静态与媒体两条线分开:一个随代码走,一个随用户走。

呈现层就绪。下一章处理用户输入——表单的渲染、校验与 ModelForm 的省力之道。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U