轻量级Django 读书笔记-第三章

静态网站生成器

参考代码

概要

  • 什么是静态网站生成器
    静态网站生成器,就是将原来的网站(可能是动态或者静态的)的每一页面转换为html文件的工具
  • 有什么好处
    1. 方便部署,不需要复杂的Web服务器,只需要能提供静态内容的Web服务器就行
    2. 便于搜索引擎爬虫抓取
    3. 可以作为dome生成工具,快速展示自己的设计和想法
  • 用什么做
    • 有很多静态网站生成器工具,我用的是Hexo
    • Django可以轻松的作为静态网站生成器使用
  • 怎么做
    1. 借助第二章内容,创建一个简易的Django项目
    2. 规划网站的基本机构,抽象为公共页,框架页,和内容页三部分
    3. 使用Django模板引擎,和视图将内容页展示为正常的网页
    4. 自定义命令执行网站静态话过程
    5. 利用Django测试客户端逐个访问内容页,将返回的内容作为html件输出到定义好的静态目录
    6. 进一步对引用的CSS和JS文件进行压缩处理
    7. 争对单个页面生成的优化
    8. 利用python的 http.server 作为Web服务器,启动静态网站

详细

网站规划

  • 基础页
    指的是网站中每个页面中固定的部分,这些部分可能是样式不变,或者文字不变等,但总有些共通之处,例如每个页面上要显示的Banner,和Footer,这些内容和结构相对固定,另外就是页面的标题,以及针对SEO优化的信息,都是相对固定的,或者说变化是有规律的,将这些部分抽取出来,作为一个基础模板页,其他页面都是从这个页面上生成或者继承的,这里会用到模板引擎,参考Django模板引擎
  • 页面框架
    有了基础页,可以不用有框架页了,但是为了让代码更灵活,以及解耦和需要一个页面框架来提供内容的组织和一些个性化的设置。
    页面框架的继承自基础页,并对基础页中定义的可重写部分做了个性化的设置,最后将内容页的内容作为模板变量替换到基础页上,从而形成完整的网页
  • 内容页
    有了上面的基础,内容也只负责具体的内容,也就是只写最终网页上主体内容的部分,不用关注公共的部分,最后,内容页的文件名将作为内容页的唯一标识,也可以理解成最终作为URL的一部分,以及作为页面个性化的一部分,比如每个页的标题

    Django模板引擎

  • Django有很强的的引擎功能,使用时需要在配置中设置 如下

    1
    2
    3
    4
    5
    6
    7
    TEMPLATES=(
    {
    'BACKEND': 'django.template.backends.django.DjangoTemplates', # 使用的模板引擎
    'DIRS': [], # 设置Django搜索模板的路径
    'APP_DIRS': True # 为True表示 在项目所在文件家的templates查找模板
    },
    )
  • 渲染模板

    1. 引用 from django.shortcuts import render
    2. 渲染 render(request, 'page.html', context)
      request为http请求,page.html为模板文件,context为模板上下文变量
      示例:
      1
      2
      3
      4
      5
      context = {
      'slug': slug,
      'page': page,
      }
      render(request, 'page.html', context)
  • 模板语法

    1
    2
    3
    4
    5

    | 场景 |语法|示例|
    |:---|:---|:---|
    |上下文|`{{ }}`|`{{ slug }}`,获取上下文变量中的slug属性,和在python中使用一样|
    |系统设置和方法|```{% %}```|```{% load staticfiles %}``` 为引入```static```系统方法|
  • 常用的系统设置和方法

    1
    2
    3
    4
    5
    6
    7
    1. ``{% load staticfiles %}``: 引入 `static`方法,可以为模板的CSS和JS文件引入提供方便
    2. ``{% static %}``: 计算一个引用文件的网站相对路径 例如 `{% static 'css/site.css' %}`
    3. ``{% include temp %}``: 包含一个模板变量(注意不是模板字符串,而是一个模板实体),即将其他模板内容合并在这里
    4. ``{% extends 'base.html' %}``: 模板的继承,表示当前模板继承自`base.html`模板
    5. ``{% block blogtag %} ... {% endblock %}``: 在父模板中表示可以被子模版重写的部分,在子模版中表示需要重写父模板的部分
    6. ``{% if slug == 'index' %} ... {% endif %}``: 表示判断,通过判断,就会显示在if范围内的内容
    7. ``{% url ... %}``:生成一个url,与``static``不同的是需要为他指定一个``view``,然后写上``view``需要的参数 例如 ``{% url 'page' 'index' %}``,表示用`view page`来生成url,且给定参数 `index`
  • 继承
    先看代码示例:
    base.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    {% load staticfiles %}
    <!DOCTYPE html>
    <html lang="en">
    <head>
    ...
    <title>{% block title %}Rapid Prototypes{% endblock %}</title>
    <link rel="stylesheet" href="{% static 'css/bootstrap.min.css'%}">
    ...
    </head>
    <body id="{% block body-id %}body{% endblock %}">
    {% block top-nav-wrapper %}
    ...
    {% endblock %}
    {% block content %}{% endblock %}
    ...

    page.html

    1
    2
    3
    4
    5
    6
    {% extends "base.html" %}
    {% block title %}{{ block.super}} - {{ slug|capfirst }}{% endblock %}
    {% block body-id %}{{ slug|slugify }}{% endblock %}
    {% block content %}
    {% include page %}
    {% endblock %}
    • page.html 继承自 base.html
    • base.html 设置了 title body-id top-nav-wrappercontent 作为可重新部分
    • page.html 重写了 title,但同时调用了父类的 title值,用 block.super
    • page.html 并没有重写 top-nav-wrapper,所以在生成的页面中沿用base.html 中定义的部分

      遍历所有页面

  • 原理是,由于所有的内容也都是定义在pages文件夹下的,而且由于url路由的设置,是将文件名作为url的路径的,所有只要遍历pages下的文件,并且合成响应的url,通过python的测试客户端就可以访问,将返回的结果放在生成文件夹中
  • 步骤
    1. 处理静态文件,不是直接将文件拷贝过去而是,利用Django内置命令 collectstatic
      call_command('collectstatic', interactive=False, clear=True, verbosity=0)
    2. 遍历页面文件夹中的文件,利用Django urls的 reverse(和模板中的url类似),将指定view的url合成出来
    3. 通过测试客户端请求页面,厉害的是,这里并不需要启动服务,测试客户端会自动合成好页面内容
    4. 将请求的结果写入到对于内容模板的文件中去