• wagtail的使用


    数据模型models中的基本字段

    templates

    template = 'home/home_page.html'
    
    • 1

    指定模板文件的位置,如果不指定,则模板文件位于本app的models同级templates文件夹下的app文件名下的与class同名的html中
    在这里插入图片描述

    字符型

    页面中展示的内容都是models中类的一个字段,在homepage添加一个subtile字段
    在这里插入图片描述
    并把它展示在页面中,如下,使用content_panels 和 FieldPanel关键字
    在这里插入图片描述
    在这里插入图片描述

    字段的实际显示名,可用verbose来处理
    迁移下数据
    打开首页编辑
    在这里插入图片描述

    目前首页是没有内容的,因为对应的渲染模板页面还没有处理。
    在模板中,所有的变量被封存到了page对象中。
    在这里插入图片描述
    {{ }}用来显示变量。

    在这里插入图片描述

    文本字段

    在models中增加一个问本字段
    在这里插入图片描述
    数据迁移下
    刷新管理页面
    多了一个content1字段
    在这里插入图片描述
    添加内容
    在这里插入图片描述
    模板页
    在这里插入图片描述

    在这里插入图片描述

    带有下拉选择的文本字段

    在blogpage中增加一个open_type字段,这个字段是通过下拉菜单选择,下拉菜单内容在 TYPE_CHIOCES 中定义死了。

        TYPE_CHIOCES = (
            ('switchTab', '底部标签'),
            ('navigate', '页面导航'),
        )
        open_type = models.CharField(max_length=20, choices=TYPE_CHIOCES, null=True, verbose_name='打开类型')
        # Export fields over the API
        api_fields = [
            APIField('image'),
            APIField('body'),
            APIField('open_type'),
        ]
    
    
        content_panels = Page.content_panels + [
            MultiFieldPanel([
                FieldPanel('date'),
                FieldPanel('authors', widget=forms.CheckboxSelectMultiple),
            ], heading="Blog information"),
            FieldPanel('image'),
            FieldPanel('open_type'),
            FieldPanel('body'),
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    富文本字段

    添加一个富文本字段
    在这里插入图片描述
    迁移数据

    在这里插入图片描述
    发布出去
    在这里插入图片描述
    模板增加标签加载和富文本的过滤器
    在这里插入图片描述
    刷新页面

    在这里插入图片描述

    图片字段

    图片的处理
    在这里插入图片描述
    迁移数据,刷新管理页面
    在这里插入图片描述

    渲染模板增加标签加载和指定图片加载尺寸
    在这里插入图片描述
    在这里插入图片描述

    图片添加cta

    文件字段

    文件处理
    在这里插入图片描述

    迁移数据刷新管理页面
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    引入bootstrap

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

    优化模板文档

    公共部分都移入到base.html中
    mysite\templates\base.html

    {% load static wagtailuserbar %}
    
    <!DOCTYPE html>
    "en">
    
        "UTF-8">
        Title<<span class="token operator">/</span>title>
        <<span class="token operator">!</span><span class="token operator">--</span> CSS <span class="token operator">--</span>>
        <link href=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"</span> rel=<span class="token string">"stylesheet"</span>>
        <<span class="token operator">!</span><span class="token operator">--</span> jQuery and JavaScript Bundle with Popper <span class="token operator">--</span>>
        <script src=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.slim.min.js"</span>><<span class="token operator">/</span>script>
        <script src=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"</span>><<span class="token operator">/</span>script>
    <<span class="token operator">/</span>head>
    <body>
    
    <nav <span class="token keyword">class</span>=<span class="token string">"navbar navbar-expand-lg navbar-light bg-light"</span>>
        <a <span class="token keyword">class</span>=<span class="token string">"navbar-brand"</span> href=<span class="token string">"#"</span>>Navbar<<span class="token operator">/</span>a>
        <button <span class="token keyword">class</span>=<span class="token string">"navbar-toggler"</span> <span class="token function">type</span>=<span class="token string">"button"</span> <span class="token keyword">data</span><span class="token operator">-</span>toggle=<span class="token string">"collapse"</span> <span class="token keyword">data</span><span class="token operator">-</span>target=<span class="token string">"#navbarSupportedContent"</span>
                aria-controls=<span class="token string">"navbarSupportedContent"</span> aria-expanded=<span class="token string">"false"</span> aria-label=<span class="token string">"Toggle navigation"</span>>
            <span <span class="token keyword">class</span>=<span class="token string">"navbar-toggler-icon"</span>><<span class="token operator">/</span>span>
        <<span class="token operator">/</span>button>
    
        <div <span class="token keyword">class</span>=<span class="token string">"collapse navbar-collapse"</span> id=<span class="token string">"navbarSupportedContent"</span>>
            <ul <span class="token keyword">class</span>=<span class="token string">"navbar-nav mr-auto"</span>>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item active"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link"</span> href=<span class="token string">"#"</span>>Home <span <span class="token keyword">class</span>=<span class="token string">"sr-only"</span>><span class="token punctuation">(</span>current<span class="token punctuation">)</span><<span class="token operator">/</span>span><<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link"</span> href=<span class="token string">"#"</span>>Link<<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item dropdown"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link dropdown-toggle"</span> href=<span class="token string">"#"</span> id=<span class="token string">"navbarDropdown"</span> role=<span class="token string">"button"</span> <span class="token keyword">data</span><span class="token operator">-</span>toggle=<span class="token string">"dropdown"</span>
                       aria-haspopup=<span class="token string">"true"</span> aria-expanded=<span class="token string">"false"</span>>
                        Dropdown
                    <<span class="token operator">/</span>a>
                    <div <span class="token keyword">class</span>=<span class="token string">"dropdown-menu"</span> aria-labelledby=<span class="token string">"navbarDropdown"</span>>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Action<<span class="token operator">/</span>a>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Another action<<span class="token operator">/</span>a>
                        <div <span class="token keyword">class</span>=<span class="token string">"dropdown-divider"</span>><<span class="token operator">/</span>div>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Something <span class="token keyword">else</span> here<<span class="token operator">/</span>a>
                    <<span class="token operator">/</span>div>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link disabled"</span> href=<span class="token string">"#"</span> tabindex=<span class="token string">"-1"</span> aria-disabled=<span class="token string">"true"</span>>Disabled<<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
            <<span class="token operator">/</span>ul>
            <form <span class="token keyword">class</span>=<span class="token string">"form-inline my-2 my-lg-0"</span>>
                <input <span class="token keyword">class</span>=<span class="token string">"form-control mr-sm-2"</span> <span class="token function">type</span>=<span class="token string">"search"</span> placeholder=<span class="token string">"Search"</span> aria-label=<span class="token string">"Search"</span>>
                <button <span class="token keyword">class</span>=<span class="token string">"btn btn-outline-success my-2 my-sm-0"</span> <span class="token function">type</span>=<span class="token string">"submit"</span>>Search<<span class="token operator">/</span>button>
            <<span class="token operator">/</span>form>
        <<span class="token operator">/</span>div>
    <<span class="token operator">/</span>nav>
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>body>
    <<span class="token operator">/</span>html>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li></ul></pre> 
    <p>定义一个内容块</p> 
    <pre data-index="3" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre> 
    <p>其他页面非共同内容包含其中,通过上面的定义的块,代入base.html中,如下所示。</p> 
    <p>home\templates\home\home_page.html</p> 
    <pre data-index="4" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> extends <span class="token string">"base.html"</span> <span class="token operator">%</span><span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailimages_tags <span class="token operator">%</span><span class="token punctuation">}</span>
        <div>
            <div <span class="token keyword">class</span>=<span class="token string">"alert alert-primary"</span> role=<span class="token string">"alert"</span>>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page<span class="token punctuation">.</span>subtitle <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <<span class="token operator">/</span>div>
            <p>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page<span class="token punctuation">.</span>content1 <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <<span class="token operator">/</span>p>
            <p>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page<span class="token punctuation">.</span>content2 <span class="token punctuation">|</span> richtext <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <<span class="token operator">/</span>p>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image page<span class="token punctuation">.</span>image fill-600x200 <span class="token operator">%</span><span class="token punctuation">}</span>
            <a href=<span class="token string">"{<!-- -->{ page.file.url }}"</span>>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page<span class="token punctuation">.</span>file <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <<span class="token operator">/</span>a>
        <<span class="token operator">/</span>div>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li></ul></pre> 
    <h2><a name="t12"></a><a id="_211"></a>模板</h2> 
    <h3><a name="t13"></a><a id="_212"></a>加载静态文件</h3> 
    <p>图片<br> <img src="https://1000bd.com/contentImg/2024/03/25/a4953bfb55a28d00.png" alt="在这里插入图片描述"><br> css<br> <img src="https://1000bd.com/contentImg/2024/03/25/5d0e7441d4ba4ce7.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t14"></a><a id="models_218"></a>引用models元素</h3> 
    <p>cta引用需要加上url,才能完整引用路径,否则引用较深目录层次会找不到<br> <img src="https://1000bd.com/contentImg/2024/03/25/14aafb49c2c1b63d.png" alt="在这里插入图片描述"></p> 
    <h2><a name="t15"></a><a id="web_223"></a>常用web组件的实现</h2> 
    <h3><a name="t16"></a><a id="banner_224"></a>带banner的首页</h3> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/bb9b4186191c465d.png" alt="在这里插入图片描述"><br> 在base.html中引入公共部分的导航条,</p> 
    <pre data-index="5" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load static wagtailuserbar <span class="token operator">%</span><span class="token punctuation">}</span>
    
    <<span class="token operator">!</span>DOCTYPE html>
    <html lang=<span class="token string">"en"</span>>
    <head>
        <meta charset=<span class="token string">"UTF-8"</span>>
        <title>Title<<span class="token operator">/</span>title>
        <<span class="token operator">!</span><span class="token operator">--</span> CSS <span class="token operator">--</span>>
        <link href=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css"</span> rel=<span class="token string">"stylesheet"</span>>
        <<span class="token operator">!</span><span class="token operator">--</span> jQuery and JavaScript Bundle with Popper <span class="token operator">--</span>>
        <script src=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.slim.min.js"</span>><<span class="token operator">/</span>script>
        <script src=<span class="token string">"https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/4.6.0/js/bootstrap.min.js"</span>><<span class="token operator">/</span>script>
    <<span class="token operator">/</span>head>
    <body>
    
    <nav <span class="token keyword">class</span>=<span class="token string">"navbar navbar-expand-lg navbar-light bg-light"</span>>
        <a <span class="token keyword">class</span>=<span class="token string">"navbar-brand"</span> href=<span class="token string">"#"</span>>Navbar<<span class="token operator">/</span>a>
        <button <span class="token keyword">class</span>=<span class="token string">"navbar-toggler"</span> <span class="token function">type</span>=<span class="token string">"button"</span> <span class="token keyword">data</span><span class="token operator">-</span>toggle=<span class="token string">"collapse"</span> <span class="token keyword">data</span><span class="token operator">-</span>target=<span class="token string">"#navbarSupportedContent"</span>
                aria-controls=<span class="token string">"navbarSupportedContent"</span> aria-expanded=<span class="token string">"false"</span> aria-label=<span class="token string">"Toggle navigation"</span>>
            <span <span class="token keyword">class</span>=<span class="token string">"navbar-toggler-icon"</span>><<span class="token operator">/</span>span>
        <<span class="token operator">/</span>button>
    
        <div <span class="token keyword">class</span>=<span class="token string">"collapse navbar-collapse"</span> id=<span class="token string">"navbarSupportedContent"</span>>
            <ul <span class="token keyword">class</span>=<span class="token string">"navbar-nav mr-auto"</span>>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item active"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link"</span> href=<span class="token string">"#"</span>>Home <span <span class="token keyword">class</span>=<span class="token string">"sr-only"</span>><span class="token punctuation">(</span>current<span class="token punctuation">)</span><<span class="token operator">/</span>span><<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link"</span> href=<span class="token string">"#"</span>>Link<<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item dropdown"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link dropdown-toggle"</span> href=<span class="token string">"#"</span> id=<span class="token string">"navbarDropdown"</span> role=<span class="token string">"button"</span> <span class="token keyword">data</span><span class="token operator">-</span>toggle=<span class="token string">"dropdown"</span>
                       aria-haspopup=<span class="token string">"true"</span> aria-expanded=<span class="token string">"false"</span>>
                        Dropdown
                    <<span class="token operator">/</span>a>
                    <div <span class="token keyword">class</span>=<span class="token string">"dropdown-menu"</span> aria-labelledby=<span class="token string">"navbarDropdown"</span>>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Action<<span class="token operator">/</span>a>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Another action<<span class="token operator">/</span>a>
                        <div <span class="token keyword">class</span>=<span class="token string">"dropdown-divider"</span>><<span class="token operator">/</span>div>
                        <a <span class="token keyword">class</span>=<span class="token string">"dropdown-item"</span> href=<span class="token string">"#"</span>>Something <span class="token keyword">else</span> here<<span class="token operator">/</span>a>
                    <<span class="token operator">/</span>div>
                <<span class="token operator">/</span>li>
                <li <span class="token keyword">class</span>=<span class="token string">"nav-item"</span>>
                    <a <span class="token keyword">class</span>=<span class="token string">"nav-link disabled"</span> href=<span class="token string">"#"</span> tabindex=<span class="token string">"-1"</span> aria-disabled=<span class="token string">"true"</span>>Disabled<<span class="token operator">/</span>a>
                <<span class="token operator">/</span>li>
            <<span class="token operator">/</span>ul>
            <form <span class="token keyword">class</span>=<span class="token string">"form-inline my-2 my-lg-0"</span>>
                <input <span class="token keyword">class</span>=<span class="token string">"form-control mr-sm-2"</span> <span class="token function">type</span>=<span class="token string">"search"</span> placeholder=<span class="token string">"Search"</span> aria-label=<span class="token string">"Search"</span>>
                <button <span class="token keyword">class</span>=<span class="token string">"btn btn-outline-success my-2 my-sm-0"</span> <span class="token function">type</span>=<span class="token string">"submit"</span>>Search<<span class="token operator">/</span>button>
            <<span class="token operator">/</span>form>
        <<span class="token operator">/</span>div>
    <<span class="token operator">/</span>nav>
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>body>
    <<span class="token operator">/</span>html>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li></ul></pre> 
    <p>在home的模板页引入banner图片和图片跳转cta</p> 
    <pre data-index="6" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token comment"># templates/home/home_page.html #}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> extends <span class="token string">"base.html"</span> <span class="token operator">%</span><span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags wagtailimages_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
    
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image self<span class="token punctuation">.</span>banner_image fill-900x300 as img <span class="token operator">%</span><span class="token punctuation">}</span>
        <div <span class="token keyword">class</span>=<span class="token string">"jumbotron"</span> style=<span class="token string">"background-image: url('{<!-- -->{ img.url }}'); background-size: cover "</span>>
            <h1 <span class="token keyword">class</span>=<span class="token string">"display-4"</span> style=<span class="token string">"color: #e6e6e6"</span>><span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> self<span class="token punctuation">.</span>banner_title <span class="token punctuation">}</span><span class="token punctuation">}</span><<span class="token operator">/</span>h1>
    
            <div <span class="token keyword">class</span>=<span class="token string">"lead"</span> style=<span class="token string">"color: #e6e6e6"</span>><span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page<span class="token punctuation">.</span>banner_subtitle<span class="token punctuation">|</span>richtext <span class="token punctuation">}</span><span class="token punctuation">}</span><<span class="token operator">/</span>div>
            <a <span class="token keyword">class</span>=<span class="token string">"btn btn-primary btn-lg"</span> href=<span class="token string">"{<!-- -->{ self.banner_cta }}"</span> role=<span class="token string">"button"</span>>详情<<span class="token operator">/</span>a>
        <<span class="token operator">/</span>div>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li></ul></pre> 
    <p>在home的models中定义数据模型</p> 
    <pre data-index="7" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># home/models.py</span>
    <span class="token keyword">from</span> django<span class="token punctuation">.</span>db import models
    
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core<span class="token punctuation">.</span>models import Page<span class="token punctuation">,</span> Orderable
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core<span class="token punctuation">.</span>fields import RichTextField
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>admin<span class="token punctuation">.</span>edit_handlers import FieldPanel<span class="token punctuation">,</span> InlinePanel<span class="token punctuation">,</span> PageChooserPanel
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>images<span class="token punctuation">.</span>edit_handlers import ImageChooserPanel
    
    
    <span class="token keyword">class</span> HomePage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        <span class="token string">'''HomePage models '''</span>
        template = <span class="token string">'home/home_page.html'</span>
        banner_title = models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length=100<span class="token punctuation">,</span> blank=True<span class="token punctuation">,</span> null=True<span class="token punctuation">)</span>
        <span class="token comment"># max_count = 1</span>
        banner_subtitle = RichTextField<span class="token punctuation">(</span>features=<span class="token punctuation">[</span><span class="token string">'bold'</span><span class="token punctuation">,</span> <span class="token string">'italic'</span><span class="token punctuation">]</span><span class="token punctuation">,</span> blank=True<span class="token punctuation">,</span> null=True<span class="token punctuation">)</span>
        banner_image = models<span class="token punctuation">.</span>ForeignKey<span class="token punctuation">(</span>
            <span class="token string">'wagtailimages.Image'</span><span class="token punctuation">,</span>
            blank=True<span class="token punctuation">,</span>
            null=True<span class="token punctuation">,</span>
            on_delete=models<span class="token punctuation">.</span>DO_NOTHING<span class="token punctuation">,</span>
            related_name=<span class="token string">"+"</span>
        <span class="token punctuation">)</span>
        banner_cta = models<span class="token punctuation">.</span>ForeignKey<span class="token punctuation">(</span>
            <span class="token string">'wagtailcore.Page'</span><span class="token punctuation">,</span>
            blank=True<span class="token punctuation">,</span>
            null=True<span class="token punctuation">,</span>
            on_delete=models<span class="token punctuation">.</span>DO_NOTHING<span class="token punctuation">,</span>
            related_name=<span class="token string">"+"</span>
    
        <span class="token punctuation">)</span>
    
        content_panels = Page<span class="token punctuation">.</span>content_panels <span class="token operator">+</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'banner_title'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'banner_subtitle'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            ImageChooserPanel<span class="token punctuation">(</span><span class="token string">'banner_image'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            PageChooserPanel<span class="token punctuation">(</span><span class="token string">'banner_cta'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    
        <span class="token punctuation">]</span>
    
        <span class="token keyword">class</span> Meta:
            verbose_name = <span class="token string">'首页这里'</span>
            verbose_name_plural = <span class="token string">'首页plural'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li></ul></pre> 
    <h3><a name="t17"></a><a id="_350"></a>页面主题</h3> 
    <pre data-index="8" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">https://bootswatch.com/
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <h3><a name="t18"></a><a id="_356"></a>轮播图</h3> 
    <pre data-index="9" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">https://v4.bootcss.com/docs/getting-started/introduction/
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <h2><a name="t19"></a><a id="StreamField__362"></a>StreamField 字段</h2> 
    <p>StreamField字段可实现多媒体的展示<br> StreamField提供了一种内容编辑模型,适用于不遵循固定结构的页面(如博客文章或新闻故事),其中文本可能会穿插副标题、图像、引述和视频。它也适用于更专业的内容类型,如地图和图表(或者,对于编程博客,代码片段)。在这个模型中,这些不同的内容类型被表示为一系列的“块”,这些块可以以任何顺序重复和排列。<br> StreamField还提供了一个丰富的API来定义您自己的块类型,范围从简单的子块集合(例如由名字、姓氏和照片组成的“person”块)到完全自定义的具有自己编辑界面的组件。在数据库中,StreamField内容存储为JSON,确保字段的完整信息内容得到保留,而不仅仅是它的HTML表示。<br> 下面展示如何使用StremField</p> 
    <h3><a name="t20"></a><a id="StreamField_367"></a>使用StreamField</h3> 
    <p>StreamField是一个模型字段,可以像任何其他字段一样在页面模型中定义:</p> 
    <pre data-index="10" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db <span class="token function">import</span> models
    
    from wagtail.models <span class="token function">import</span> Page
    from wagtail.fields <span class="token function">import</span> StreamField
    from wagtail <span class="token function">import</span> blocks
    from wagtail.admin.panels <span class="token function">import</span> FieldPanel
    from wagtail.images.blocks <span class="token function">import</span> ImageChooserBlock
    
    class BlogPage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        author <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
        <span class="token function">date</span> <span class="token operator">=</span> models.DateField<span class="token punctuation">(</span><span class="token string">"Post date"</span><span class="token punctuation">)</span>
        body <span class="token operator">=</span> StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
            <span class="token punctuation">(</span><span class="token string">'heading'</span>, blocks.CharBlock<span class="token punctuation">(</span>form_classname<span class="token operator">=</span><span class="token string">"title"</span><span class="token punctuation">))</span>,
            <span class="token punctuation">(</span><span class="token string">'paragraph'</span>, blocks.RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">))</span>,
            <span class="token punctuation">(</span><span class="token string">'image'</span>, ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">))</span>,
        <span class="token punctuation">]</span>, <span class="token assign-left variable">use_json_field</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
    
        content_panels <span class="token operator">=</span> Page.content_panels + <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'author'</span><span class="token punctuation">)</span>,
            FieldPanel<span class="token punctuation">(</span><span class="token string">'date'</span><span class="token punctuation">)</span>,
            FieldPanel<span class="token punctuation">(</span><span class="token string">'body'</span><span class="token punctuation">)</span>,
        <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li></ul></pre> 
    <p>在本例中,BlogPage的body字段被定义为StreamField,在StreamField中,作者可以使用三种不同的块类型组成内容:标题、段落和图像,这些块可以按任何顺序使用和重复。可供作者使用的块类型定义为(name, block_type)元组列表:“name”用于标识模板中的块类型,并且应遵循变量名称的标准Python约定:小写和下划线,无空格。</p> 
    <p>您可以在StreamField块参照中找到可用块类型的完整列表。</p> 
    <h3><a name="t21"></a><a id="_398"></a>模板呈现</h3> 
    <p>StreamField像展示单个块一样,把stream 的内容作为整一个整体展示为HTML。要将此HTML包含到你的页面中,请使用{% include_block %}标记:</p> 
    <pre data-index="11" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
     <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block page<span class="token punctuation">.</span>body <span class="token operator">%</span><span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li></ul></pre> 
    <p>实际中使用<br> mysite\templates\flex\flex_page.html</p> 
    <pre data-index="12" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> extends <span class="token string">"base.html"</span> <span class="token operator">%</span><span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags wagtailimages_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> block content <span class="token operator">%</span><span class="token punctuation">}</span>
        <div>
            <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> self<span class="token punctuation">.</span>subtitle <span class="token punctuation">}</span><span class="token punctuation">}</span>
        <<span class="token operator">/</span>div>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> block in page<span class="token punctuation">.</span>content <span class="token operator">%</span><span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block block <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endblock <span class="token operator">%</span><span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre> 
    <p>content来自这里<br> flex\models.py</p> 
    <pre data-index="13" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">from</span> django<span class="token punctuation">.</span>db import models
    <span class="token keyword">from</span> django<span class="token punctuation">.</span>db import models
    <span class="token keyword">from</span> modelcluster<span class="token punctuation">.</span>fields import ParentalKey
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core import blocks
    <span class="token keyword">from</span> streams import myblocks
    
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core<span class="token punctuation">.</span>models import Page<span class="token punctuation">,</span> Orderable
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core<span class="token punctuation">.</span>fields import RichTextField<span class="token punctuation">,</span> StreamField
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>admin<span class="token punctuation">.</span>edit_handlers import FieldPanel<span class="token punctuation">,</span> InlinePanel<span class="token punctuation">,</span> PageChooserPanel<span class="token punctuation">,</span> StreamFieldPanel
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>images<span class="token punctuation">.</span>edit_handlers import ImageChooserPanel
    
    
    <span class="token keyword">class</span> FlexPage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        template = <span class="token string">'flex/flex_page.html'</span>
    
        subtitle = models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length=100<span class="token punctuation">,</span> blank=True<span class="token punctuation">,</span> null=True<span class="token punctuation">)</span>
        content = StreamField<span class="token punctuation">(</span>
            <span class="token punctuation">[</span>
                <span class="token punctuation">(</span><span class="token string">'title_and_text'</span><span class="token punctuation">,</span> myblocks<span class="token punctuation">.</span>TitleAndTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">]</span><span class="token punctuation">,</span>
            blank=True<span class="token punctuation">,</span>
            null=True<span class="token punctuation">,</span>
        <span class="token punctuation">)</span>
    
        content_panels = Page<span class="token punctuation">.</span>content_panels <span class="token operator">+</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'subtitle'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            StreamFieldPanel<span class="token punctuation">(</span><span class="token string">'content'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    
        <span class="token punctuation">]</span>
    
        <span class="token keyword">class</span> Meta:
            verbose_name = <span class="token string">'Flex Page'</span>
            verbose_name_plural = <span class="token string">'Flex Pages'</span>
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li></ul></pre> 
    <p>为了更好地控制特定块类型的渲染,每个块对象都提供块类型和值特性:</p> 
    <pre data-index="14" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
     <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    
    <article>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> block in page<span class="token punctuation">.</span>body <span class="token operator">%</span><span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">if</span> block<span class="token punctuation">.</span>block_type == <span class="token string">'heading'</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <h1><span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> block<span class="token punctuation">.</span>value <span class="token punctuation">}</span><span class="token punctuation">}</span><<span class="token operator">/</span>h1>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">else</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <section <span class="token keyword">class</span>=<span class="token string">"block-{<!-- -->{ block.block_type }}"</span>>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block block <span class="token operator">%</span><span class="token punctuation">}</span>
                <<span class="token operator">/</span>section>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endif <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>article>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li></ul></pre> 
    <h3><a name="t22"></a><a id="_482"></a>组合块</h3> 
    <p>除了直接在StreamField中使用内置块类型外,还可以通过各种方式组合子块来构造新的块类型。这方面的例子包括:</p> 
    <ul><li>由图像选择器和文本字段组成的“带标题的图像”块</li><li>一个“相关链接”部分,作者可以提供任何数量的链接到其他网页</li><li>一种幻灯片放映块,其中每张幻灯片可以是图像、文本或视频,按任何顺序排列</li></ul> 
    <p>一旦以这种方式构建了新的块类型,就可以在任何使用内置块类型的地方使用它—包括将它用作另一个块类型的组件。例如,您可以定义一个图像库块,其中每个项目都是一个“带标题的图像”块。</p> 
    <h3><a name="t23"></a><a id="StructBlock_492"></a>StructBlock</h3> 
    <p>StructBlock允许您将多个“子”块组合在一起,以显示为单个块。子块作为(名称,块类型)元组列表传递给StructBlock:</p> 
    <pre data-index="15" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> body = StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
         <span class="token punctuation">(</span><span class="token string">'person'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">(</span><span class="token punctuation">[</span>
             <span class="token punctuation">(</span><span class="token string">'first_name'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'surname'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'photo'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'biography'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'heading'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'paragraph'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
     <span class="token punctuation">]</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li></ul></pre> 
    <p>其中person对应了一个StructBlock</p> 
    <p>在读回StreamField的内容时(例如在呈现模板时),StructBlock的值是一个类似dict的对象,其键与定义中给出的块名相对应:</p> 
    <pre data-index="16" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><article>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> block in page<span class="token punctuation">.</span>body <span class="token operator">%</span><span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">if</span> block<span class="token punctuation">.</span>block_type == <span class="token string">'person'</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <div <span class="token keyword">class</span>=<span class="token string">"person"</span>>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image block<span class="token punctuation">.</span>value<span class="token punctuation">.</span>photo width-400 <span class="token operator">%</span><span class="token punctuation">}</span>
                    <h2><span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> block<span class="token punctuation">.</span>value<span class="token punctuation">.</span>first_name <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> block<span class="token punctuation">.</span>value<span class="token punctuation">.</span>surname <span class="token punctuation">}</span><span class="token punctuation">}</span><<span class="token operator">/</span>h2>
                    <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> block<span class="token punctuation">.</span>value<span class="token punctuation">.</span>biography <span class="token punctuation">}</span><span class="token punctuation">}</span>
                <<span class="token operator">/</span>div>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">else</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <span class="token punctuation">(</span>rendering <span class="token keyword">for</span> other block types<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endif <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>article>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre> 
    <h3><a name="t24"></a><a id="_528"></a>子类化结构块</h3> 
    <p>在StreamField定义中放置StructBlock的子块列表通常很难读懂,并且使得同一块很难在多个位置重用。因此,StructBlock可以子类化,子块定义为子类上的属性。上例中的“person”块可以重写为:</p> 
    <pre data-index="17" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> PersonBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">)</span>:
        first_name = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        surname = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        photo = ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span>
        biography = blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li></ul></pre> 
    <p>PersonBlock可以在StreamField定义中使用,使用方式与内置块类型相同:</p> 
    <pre data-index="18" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">body = StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
        <span class="token punctuation">(</span><span class="token string">'person'</span><span class="token punctuation">,</span> PersonBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">(</span><span class="token string">'heading'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">(</span><span class="token string">'paragraph'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    <span class="token punctuation">]</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <h3><a name="t25"></a><a id="Block_icons_549"></a>Block icons</h3> 
    <p>在内容作者用于向StreamField添加新块的菜单中,每个块类型都有一个关联的图标。对于StructBlock和其他结构块类型,将使用占位符图标,因为这些块的用途特定于您的项目。要设置自定义图标,请将选项图标作为<a href="https://so.csdn.net/so/search?q=%E5%85%B3%E9%94%AE%E5%AD%97%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92&spm=1001.2101.3001.7020" target="_blank" class="hl hl-1" data-report-view="{"spm":"1001.2101.3001.7020","dest":"https://so.csdn.net/so/search?q=%E5%85%B3%E9%94%AE%E5%AD%97%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92&spm=1001.2101.3001.7020","extra":"{\"searchword\":\"关键字参数传递\"}"}" data-report-click="{"spm":"1001.2101.3001.7020","dest":"https://so.csdn.net/so/search?q=%E5%85%B3%E9%94%AE%E5%AD%97%E5%8F%82%E6%95%B0%E4%BC%A0%E9%80%92&spm=1001.2101.3001.7020","extra":"{\"searchword\":\"关键字参数传递\"}"}" data-tit="关键字参数传递" data-pretit="关键字参数传递">关键字参数传递</a>给StructBlock,或作为元类的属性传递:</p> 
    <pre data-index="19" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> body = StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
         <span class="token punctuation">(</span><span class="token string">'person'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">(</span><span class="token punctuation">[</span>
             <span class="token punctuation">(</span><span class="token string">'first_name'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'surname'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'photo'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token punctuation">(</span><span class="token string">'biography'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">]</span><span class="token punctuation">,</span> icon=<span class="token string">'user'</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'heading'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'paragraph'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
     <span class="token punctuation">]</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li></ul></pre> 
    <p>其中的icon=‘user’</p> 
    <pre data-index="20" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> <span class="token keyword">class</span> PersonBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">)</span>:
         first_name = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
         surname = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
         photo = ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span>
         biography = blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
         <span class="token keyword">class</span> Meta:
             icon = <span class="token string">'user'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li></ul></pre> 
    <h3><a name="t26"></a><a id="ListBlock_579"></a>ListBlock</h3> 
    <p>ListBlock定义了一个重复块,允许内容作者插入任意多个特定块类型的实例。例如,由多个图像组成的“多媒体资料”块可以定义如下:</p> 
    <pre data-index="21" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> body = StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
         <span class="token punctuation">(</span><span class="token string">'gallery'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>ListBlock<span class="token punctuation">(</span>ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'heading'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'paragraph'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
     <span class="token punctuation">]</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>在读回StreamField的内容时(例如在呈现模板时),ListBlock的值是子值的列表:</p> 
    <pre data-index="22" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><article>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> block in page<span class="token punctuation">.</span>body <span class="token operator">%</span><span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">if</span> block<span class="token punctuation">.</span>block_type == <span class="token string">'gallery'</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <ul <span class="token keyword">class</span>=<span class="token string">"gallery"</span>>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> img in block<span class="token punctuation">.</span>value <span class="token operator">%</span><span class="token punctuation">}</span>
                        <li><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image img width-400 <span class="token operator">%</span><span class="token punctuation">}</span><<span class="token operator">/</span>li>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
                <<span class="token operator">/</span>ul>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">else</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <span class="token punctuation">(</span>rendering <span class="token keyword">for</span> other block types<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endif <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>article>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre> 
    <h3><a name="t27"></a><a id="StreamBlock_608"></a>StreamBlock</h3> 
    <p>StreamBlock定义了一组子块类型,这些子块类型可以通过与StreamField本身相同的机制以任何顺序混合和重复。例如,支持图像和视频幻灯片的轮播图可以定义如下:</p> 
    <pre data-index="23" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> body = StreamField<span class="token punctuation">(</span><span class="token punctuation">[</span>
         <span class="token punctuation">(</span><span class="token string">'carousel'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>StreamBlock<span class="token punctuation">(</span><span class="token punctuation">[</span>
             <span class="token string">'image'</span>: ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
             <span class="token string">'video'</span>: EmbedBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">]</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'heading'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'paragraph'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
         <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
     <span class="token punctuation">]</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li></ul></pre> 
    <p>StreamBlock也可以与StructBlock相同的方式子类化,子块被指定为类上的属性:</p> 
    <pre data-index="24" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> PersonBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StreamBlock<span class="token punctuation">)</span>:
        image = ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        video = EmbedBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
        <span class="token keyword">class</span> Meta:
            icon = <span class="token string">'image'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>以这种方式定义的StreamBlock子类也可以传递给StreamField定义,而不是传递块类型列表。这允许设置一组公共块类型,以便在多个页面类型上使用:</p> 
    <pre data-index="25" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> CommonContentBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StreamBlock<span class="token punctuation">)</span>:
        heading = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>form_classname=<span class="token string">"full title"</span><span class="token punctuation">)</span>
        paragraph = blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        image = ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
    
    <span class="token keyword">class</span> BlogPage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        body = StreamField<span class="token punctuation">(</span>CommonContentBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li></ul></pre> 
    <p>当读回StreamField的内容时,StreamBlock的值是具有block类型和值属性的块对象序列,就像StreamField本身的顶级值一样。</p> 
    <pre data-index="26" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><article>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> block in page<span class="token punctuation">.</span>body <span class="token operator">%</span><span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">if</span> block<span class="token punctuation">.</span>block_type == <span class="token string">'carousel'</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <ul <span class="token keyword">class</span>=<span class="token string">"carousel"</span>>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">for</span> slide in block<span class="token punctuation">.</span>value <span class="token operator">%</span><span class="token punctuation">}</span>
                        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">if</span> slide<span class="token punctuation">.</span>block_type == <span class="token string">'image'</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                            <li <span class="token keyword">class</span>=<span class="token string">"image"</span>><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image slide<span class="token punctuation">.</span>value width-200 <span class="token operator">%</span><span class="token punctuation">}</span><<span class="token operator">/</span>li>
                        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">else</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                            <li> <span class="token keyword">class</span>=<span class="token string">"video"</span>><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block slide <span class="token operator">%</span><span class="token punctuation">}</span><<span class="token operator">/</span>li>
                        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endif <span class="token operator">%</span><span class="token punctuation">}</span>
                    <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
                <<span class="token operator">/</span>ul>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> <span class="token keyword">else</span> <span class="token operator">%</span><span class="token punctuation">}</span>
                <span class="token punctuation">(</span>rendering <span class="token keyword">for</span> other block types<span class="token punctuation">)</span>
            <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endif <span class="token operator">%</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> endfor <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>article>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li></ul></pre> 
    <h3><a name="t28"></a><a id="Perblock_templates_666"></a>Per-block templates</h3> 
    <p>默认情况下,每个块都使用简单、最小的HTML标记呈现,或者根本不使用任何标记。例如,CharBlock值呈现为纯文本,而ListBlock在</p> 
    <ul><li>
      包装器中输出其子块。要使用自己的自定义HTML呈现覆盖此选项,可以将模板参数传递给块,给出要呈现的模板文件的文件名。这对于从StructBlock派生的自定义块类型特别有用: 
    </li></ul> 
    <p></p> 
    <pre data-index="27" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">(</span><span class="token string">'person'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">(</span>
        <span class="token punctuation">[</span>
            <span class="token punctuation">(</span><span class="token string">'first_name'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">(</span><span class="token string">'surname'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">(</span><span class="token string">'photo'</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            <span class="token punctuation">(</span><span class="token string">'biography'</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">]</span><span class="token punctuation">,</span>
        template=<span class="token string">'myapp/blocks/person.html'</span><span class="token punctuation">,</span>
        icon=<span class="token string">'user'</span>
    <span class="token punctuation">)</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li></ul></pre> 
    <p>Or, when defined as a subclass of StructBlock:<br> 或者,当定义为结构块的子类时</p> 
    <pre data-index="28" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> PersonBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">)</span>:
        first_name = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        surname = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        photo = ImageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span>
        biography = blocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
    
        <span class="token keyword">class</span> Meta:
            template = <span class="token string">'myapp/blocks/person.html'</span>
            icon = <span class="token string">'user'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li></ul></pre> 
    <p>在模板中,可以将块值作为变量值进行访问:</p> 
    <pre data-index="29" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailimages_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
    <div <span class="token keyword">class</span>=<span class="token string">"person"</span>>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image value<span class="token punctuation">.</span>photo width-400 <span class="token operator">%</span><span class="token punctuation">}</span>
        <h2><span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> value<span class="token punctuation">.</span>first_name <span class="token punctuation">}</span><span class="token punctuation">}</span> <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> value<span class="token punctuation">.</span>surname <span class="token punctuation">}</span><span class="token punctuation">}</span><<span class="token operator">/</span>h2>
        <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> value<span class="token punctuation">.</span>biography <span class="token punctuation">}</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>div>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li></ul></pre> 
    <p>或</p> 
    <pre data-index="30" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> load wagtailcore_tags wagtailimages_tags <span class="token operator">%</span><span class="token punctuation">}</span>
    
    <div <span class="token keyword">class</span>=<span class="token string">"person"</span>>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> image value<span class="token punctuation">.</span>photo width-400 <span class="token operator">%</span><span class="token punctuation">}</span>
        <h2><span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block value<span class="token punctuation">.</span>first_name <span class="token operator">%</span><span class="token punctuation">}</span> <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block value<span class="token punctuation">.</span>surname <span class="token operator">%</span><span class="token punctuation">}</span><<span class="token operator">/</span>h2>
        <span class="token punctuation">{<!-- --></span><span class="token operator">%</span> include_block value<span class="token punctuation">.</span>biography <span class="token operator">%</span><span class="token punctuation">}</span>
    <<span class="token operator">/</span>div>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li></ul></pre> 
    <p>Like Django’s {% include %} tag, {% include_block %} also allows passing additional variables to the included template, through the syntax {% include_block my_block with foo=“bar” %}:<br> As well as passing variables from the parent template, block subclasses can pass additional template variables of their own by overriding the get_context method:</p> 
    <h3><a name="t29"></a><a id="classapi_725"></a>重写class定义获取更多api数据</h3> 
    <p>从Wagtail 1.9开始,您可以通过覆盖Block上的get_api_representation()方法来在StreamField中修改Block的API表示形式。</p> 
    <pre data-index="31" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">假如在blocks.py中定义了这个类
        <span class="token comment"># 增加的定义</span>
    from wagtail.images.blocks <span class="token function">import</span> ImageChooserBlock as DefaultImageChooserBlock
    
    class ImageChooserBlock<span class="token punctuation">(</span>DefaultImageChooserBlock<span class="token punctuation">)</span>:
        def get_api_representation<span class="token punctuation">(</span>self, value, <span class="token assign-left variable">context</span><span class="token operator">=</span>None<span class="token punctuation">)</span>:
            <span class="token keyword">if</span> value:
                <span class="token builtin class-name">return</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token string">'id'</span><span class="token builtin class-name">:</span> value.id,
                    <span class="token string">'title'</span><span class="token builtin class-name">:</span> value.title,
                    <span class="token comment"># 'large': value.get_rendition('width-1000').attrs_dict,</span>
                    <span class="token string">'mobile'</span><span class="token builtin class-name">:</span> value.get_rendition<span class="token punctuation">(</span><span class="token string">'width-320'</span><span class="token punctuation">)</span>.attrs_dict,
                    <span class="token comment"># 'thumbnail': value.get_rendition('fill-120x120').attrs_dict,</span>
                <span class="token punctuation">}</span>
    
    
     <span class="token comment"># 这里引用  ImageChooserBlock          </span>
    class ImageBlock<span class="token punctuation">(</span>StructBlock<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        Custom <span class="token variable"><span class="token variable">`</span>StructBlock<span class="token variable">`</span></span> <span class="token keyword">for</span> utilizing images with associated caption and
        attribution data
        <span class="token string">""</span>"
    
        image <span class="token operator">=</span> ImageChooserBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>True<span class="token punctuation">)</span>
        caption <span class="token operator">=</span> CharBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>False<span class="token punctuation">)</span>
        attribution <span class="token operator">=</span> CharBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>False<span class="token punctuation">)</span>
    
        class Meta:
            icon <span class="token operator">=</span> <span class="token string">"image"</span>
            template <span class="token operator">=</span> <span class="token string">"blocks/image_block.html"</span>
    
    
    
    <span class="token comment"># StreamBlocks  这里引用ImageBlock</span>
    class BaseStreamBlock<span class="token punctuation">(</span>StreamBlock<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        Define the custom blocks that <span class="token variable"><span class="token variable">`</span>StreamField<span class="token variable">`</span></span> will utilize
        <span class="token string">""</span>"
    
        heading_block <span class="token operator">=</span> HeadingBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        paragraph_block <span class="token operator">=</span> RichTextBlock<span class="token punctuation">(</span>
            <span class="token assign-left variable">icon</span><span class="token operator">=</span><span class="token string">"pilcrow"</span>, <span class="token assign-left variable">template</span><span class="token operator">=</span><span class="token string">"blocks/paragraph_block.html"</span>
        <span class="token punctuation">)</span>
        image_block <span class="token operator">=</span> ImageBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>
        block_quote <span class="token operator">=</span> BlockQuote<span class="token punctuation">(</span><span class="token punctuation">)</span>
        embed_block <span class="token operator">=</span> EmbedBlock<span class="token punctuation">(</span>
            <span class="token assign-left variable">help_text</span><span class="token operator">=</span><span class="token string">"Insert an embed URL e.g https://www.baidu.com"</span>,
            <span class="token assign-left variable">icon</span><span class="token operator">=</span><span class="token string">"media"</span>,
            <span class="token assign-left variable">template</span><span class="token operator">=</span><span class="token string">"blocks/embed_block.html"</span>,
        <span class="token punctuation">)</span>            
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li></ul></pre> 
    <p>然后你在引用使用BaseStreamBlock时,就可以获得较多的image的数据,在api调用中有用。</p> 
    <h2><a name="t30"></a><a id="card_780"></a>card</h2> 
    <p>有时,您需要一个可以有多个重复内容区域的StreamField。一个很好的例子是被称为卡片的设计组件。在这里,我们将探讨一个ListBlock,使我们能够使用自定义数据、ImageChooserBlock、PageChooserBlock以及如何在Wagtail CMS模板中循环使用ListBlock创建无限的卡片。<br> myblocks.py增加以下内容</p> 
    <pre data-index="32" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> Cardblock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">)</span>:
        title = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span>help_text=<span class="token string">'add your title here'</span><span class="token punctuation">)</span>
        <span class="token comment"># text = blocks.TextBlock(required=True,help_text='add your text here')</span>
        cards = blocks<span class="token punctuation">.</span>ListBlock<span class="token punctuation">(</span>
            blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">(</span>
                <span class="token punctuation">[</span>
                    <span class="token punctuation">(</span><span class="token string">'image'</span><span class="token punctuation">,</span>ImageChooserBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">'title'</span><span class="token punctuation">,</span>blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span> max_length=40<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">'text'</span><span class="token punctuation">,</span>blocks<span class="token punctuation">.</span>TextBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span>max_length=200<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">'button_page'</span><span class="token punctuation">,</span>blocks<span class="token punctuation">.</span>PageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">'button_url'</span><span class="token punctuation">,</span>blocks<span class="token punctuation">.</span>URLBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token punctuation">]</span>
            <span class="token punctuation">)</span>
        <span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li></ul></pre> 
    <p>flex/models.py增加以下内容</p> 
    <pre data-index="33" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> FlexPage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        template = <span class="token string">'flex/flex_page.html'</span>
    
        subtitle = models<span class="token punctuation">.</span>CharField<span class="token punctuation">(</span>max_length=100<span class="token punctuation">,</span> blank=True<span class="token punctuation">,</span> null=True<span class="token punctuation">)</span>
        content = StreamField<span class="token punctuation">(</span>
            <span class="token punctuation">[</span>
                <span class="token punctuation">(</span><span class="token string">'title_and_text'</span><span class="token punctuation">,</span> myblocks<span class="token punctuation">.</span>TitleAndTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token punctuation">(</span><span class="token string">'full_richtext'</span><span class="token punctuation">,</span> myblocks<span class="token punctuation">.</span>RichTextBlock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token punctuation">(</span><span class="token string">'cards'</span><span class="token punctuation">,</span>myblocks<span class="token punctuation">.</span>Cardblock<span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>    <span class="token comment">## add is here</span>
    
            <span class="token punctuation">]</span><span class="token punctuation">,</span>
            blank=True<span class="token punctuation">,</span>
            null=True<span class="token punctuation">,</span>
        <span class="token punctuation">)</span>
    
        content_panels = Page<span class="token punctuation">.</span>content_panels <span class="token operator">+</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'subtitle'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
            StreamFieldPanel<span class="token punctuation">(</span><span class="token string">'content'</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
    
        <span class="token punctuation">]</span>
    
        <span class="token keyword">class</span> Meta:
            verbose_name = <span class="token string">'Flex Page'</span>
            verbose_name_plural = <span class="token string">'Flex Pages'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li></ul></pre> 
    <p>Streams/myblocks.py</p> 
    <pre data-index="34" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">class</span> CardBlock<span class="token punctuation">(</span>blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">)</span>:
        <span class="token string">""</span><span class="token string">"Cards with image and text and button(s)."</span><span class="token string">""</span>
    
        title = blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span> help_text=<span class="token string">"Add your title"</span><span class="token punctuation">)</span>
    
        cards = blocks<span class="token punctuation">.</span>ListBlock<span class="token punctuation">(</span>
            blocks<span class="token punctuation">.</span>StructBlock<span class="token punctuation">(</span>
                <span class="token punctuation">[</span>
                    <span class="token punctuation">(</span><span class="token string">"image"</span><span class="token punctuation">,</span> ImageChooserBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">"title"</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>CharBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span> max_length=40<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">"text"</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>TextBlock<span class="token punctuation">(</span>required=True<span class="token punctuation">,</span> max_length=200<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span><span class="token string">"button_page"</span><span class="token punctuation">,</span> blocks<span class="token punctuation">.</span>PageChooserBlock<span class="token punctuation">(</span>required=False<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">(</span>
                        <span class="token string">"button_url"</span><span class="token punctuation">,</span>
                        blocks<span class="token punctuation">.</span>URLBlock<span class="token punctuation">(</span>
                            required=False<span class="token punctuation">,</span>
                            help_text=<span class="token string">"If the button page above is selected, that will be used first."</span><span class="token punctuation">,</span>  <span class="token comment"># noqa</span>
                        <span class="token punctuation">)</span><span class="token punctuation">,</span>
                    <span class="token punctuation">)</span><span class="token punctuation">,</span>
                <span class="token punctuation">]</span>
            <span class="token punctuation">)</span>
        <span class="token punctuation">)</span>
    
        <span class="token keyword">class</span> Meta:  <span class="token comment"># noqa</span>
            template = <span class="token string">"streams/cards_block.html"</span>
            icon = <span class="token string">"placeholder"</span>
            label = <span class="token string">"Staff Cards"</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li></ul></pre> 
    <p>刷新管理页面已增加card<br> <img src="https://1000bd.com/contentImg/2024/03/25/6f6c405cf44f4989.png" alt="在这里插入图片描述"></p> 
    <h2><a name="t31"></a><a id="StreamField_864"></a>StreamField实例</h2> 
    <p>首先创建一个新的app</p> 
    <pre data-index="35" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">(</span>env<span class="token punctuation">)</span> C:<span class="token punctuation">\</span>djproject<span class="token punctuation">\</span>wagprj<span class="token punctuation">\</span>mysite<span class="token operator">></span>django-admin startapp article
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>注册到配置文件base.py<br> <img src="https://1000bd.com/contentImg/2024/03/25/24ae5bf2372b6639.png" alt="在这里插入图片描述"><br> article\models.py</p> 
    <pre data-index="36" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from wagtail.core.models <span class="token function">import</span> Page, Orderable
    from django.db <span class="token function">import</span> models
    from wagtail.images.blocks <span class="token function">import</span> ImageChooserBlock
    from wagtail.core <span class="token function">import</span> blocks
    
    from wagtail.core.models <span class="token function">import</span> Page
    from wagtail.core.fields <span class="token function">import</span> RichTextField, StreamField
    from wagtail.admin.edit_handlers <span class="token function">import</span> FieldPanel, InlinePanel, StreamFieldPanel
    
    
    class Article<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        intro <span class="token operator">=</span> models.TextField<span class="token punctuation">(</span>blank<span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        content <span class="token operator">=</span> StreamField<span class="token punctuation">(</span>
            <span class="token punctuation">[</span>
                <span class="token punctuation">(</span><span class="token string">'subtitle'</span>, blocks.TextBlock<span class="token punctuation">(</span><span class="token punctuation">))</span>,
                <span class="token punctuation">(</span><span class="token string">'paragraph'</span>, blocks.TextBlock<span class="token punctuation">(</span><span class="token punctuation">))</span>,
                <span class="token punctuation">(</span><span class="token string">'image'</span>, ImageChooserBlock<span class="token punctuation">(</span><span class="token punctuation">))</span>,
            <span class="token punctuation">]</span>
        <span class="token punctuation">)</span>
    
        content_panels <span class="token operator">=</span> Page.content_panels + <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'intro'</span><span class="token punctuation">)</span>,
            StreamFieldPanel<span class="token punctuation">(</span><span class="token string">'content'</span><span class="token punctuation">)</span>,
        <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li></ul></pre> 
    <p>做下数据迁移<br> 管理页面在首页下增加一个子页面,类型选article<br> <img src="https://1000bd.com/contentImg/2024/03/25/1b73a094d6f977cb.png" alt="在这里插入图片描述"></p> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/7e99bd30baaf5da8.png" alt="在这里插入图片描述"><br> 还不能访问,需要增加对应的模板</p> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/544a885f5e5bca93.png" alt="在这里插入图片描述"><br> 创建模板文件<br> <img src="https://1000bd.com/contentImg/2024/03/25/d2a6689334ed3abe.png" alt="在这里插入图片描述"><br> article\templates\article\article.html<br> 内容替换如下</p> 
    <pre data-index="37" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">'base.html'</span> %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block content %<span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page.title <span class="token punctuation">}</span><span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page.intro <span class="token punctuation">}</span><span class="token punctuation">}</span>
    
        <span class="token punctuation">{<!-- --></span>% <span class="token keyword">for</span> <span class="token for-or-select variable">item</span> <span class="token keyword">in</span> page.content %<span class="token punctuation">}</span>
            <span class="token operator"><</span>div<span class="token operator">></span>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> item <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <span class="token operator"><</span>/div<span class="token operator">></span>
        <span class="token punctuation">{<!-- --></span>% endfor %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/4d378b8ebbea498e.png" alt="在这里插入图片描述"><br> 完善一下,增加单独处理标签的能力</p> 
    <pre data-index="38" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">'base.html'</span> %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block content %<span class="token punctuation">}</span>
        <span class="token operator"><</span>div<span class="token operator">></span>
            <span class="token operator"><</span>h<span class="token operator"><span class="token file-descriptor important">2</span>></span>
                <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> page.title <span class="token punctuation">}</span><span class="token punctuation">}</span>
            <span class="token operator"><</span>/h<span class="token operator"><span class="token file-descriptor important">2</span>></span>
        <span class="token operator"><</span>/div<span class="token operator">></span>
    
        <span class="token punctuation">{<!-- --></span>% <span class="token keyword">for</span> <span class="token for-or-select variable">item</span> <span class="token keyword">in</span> page.content %<span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span>% <span class="token keyword">if</span> item.block_type <span class="token operator">==</span> <span class="token string">'subtitle'</span> %<span class="token punctuation">}</span>
                <span class="token operator"><</span>div<span class="token operator">></span>
                    <span class="token operator"><</span>h<span class="token operator"><span class="token file-descriptor important">4</span>></span>
                        <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> item <span class="token punctuation">}</span><span class="token punctuation">}</span>
                    <span class="token operator"><</span>/h<span class="token operator"><span class="token file-descriptor important">4</span>></span>
                <span class="token operator"><</span>/div<span class="token operator">></span>
            <span class="token punctuation">{<!-- --></span>% endif %<span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span>% <span class="token keyword">if</span> item.block_type <span class="token operator">==</span> <span class="token string">'paragraph'</span> %<span class="token punctuation">}</span>
                <span class="token operator"><</span>div<span class="token operator">></span>
                    <span class="token operator"><</span>p <span class="token assign-left variable">style</span><span class="token operator">=</span><span class="token string">"color: #308282"</span><span class="token operator">></span>
                        <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> item <span class="token punctuation">}</span><span class="token punctuation">}</span>
                    <span class="token operator"><</span>/p<span class="token operator">></span>
                <span class="token operator"><</span>/div<span class="token operator">></span>
            <span class="token punctuation">{<!-- --></span>% endif %<span class="token punctuation">}</span>
            <span class="token punctuation">{<!-- --></span>% <span class="token keyword">if</span> item.block_type <span class="token operator">==</span> <span class="token string">'image'</span> %<span class="token punctuation">}</span>
                <span class="token operator"><</span>div<span class="token operator">></span>
                    <span class="token punctuation">{<!-- --></span><span class="token punctuation">{<!-- --></span> item <span class="token punctuation">}</span><span class="token punctuation">}</span>
                <span class="token operator"><</span>/div<span class="token operator">></span>
            <span class="token punctuation">{<!-- --></span>% endif %<span class="token punctuation">}</span>
        <span class="token punctuation">{<!-- --></span>% endfor %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li></ul></pre> 
    <h2><a name="t32"></a><a id="snippets_972"></a>snippets</h2> 
    <h3><a name="t33"></a><a id="register_snippet_Snippet__973"></a>以register_snippet 作为装饰器定义Snippet 数据模型</h3> 
    <p>snippets是一小段内容,而不是一个完整的web页面。一般被用来作为第二种内容展示,如,文章头部,注脚,侧部栏目,在管理后台可以进行编辑。snippets是一个Django 数据模型,没有继承Page类,因此没有组织到wagtail的目录树中。但是,他们仍然可以被编辑,在代码中以register_snippet 作为装饰,并通过访问后台面板即可访问。<br> snippets 缺乏很多pages的特性,比如,wagtail管理后台可排序,有一个确定的url,使用时候需要根据你的内容来权衡是否使用。</p> 
    <pre data-index="39" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db <span class="token function">import</span> models
    
    from wagtail.admin.panels <span class="token function">import</span> FieldPanel
    from wagtail.snippets.models <span class="token function">import</span> register_snippet
    
    <span class="token comment"># ...</span>
    
    @register_snippet
    class Advert<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        url <span class="token operator">=</span> models.URLField<span class="token punctuation">(</span>null<span class="token operator">=</span>True, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        text <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
    
        panels <span class="token operator">=</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">"url"</span><span class="token punctuation">)</span>,
            FieldPanel<span class="token punctuation">(</span><span class="token string">"text"</span><span class="token punctuation">)</span>,
        <span class="token punctuation">]</span>
    
        def __str__<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
            <span class="token builtin class-name">return</span> self.text
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p>如果不清楚是在哪里定义了snippet,可以在后台控制面板中打开snippet编辑页面,从地址栏可定位代码位置。<br> <img src="https://1000bd.com/contentImg/2024/03/25/3609ea4933bb2ff4.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t34"></a><a id="_register_snippet__1003"></a>使用 register_snippet 作为函数</h3> 
    <p>虽然 @register_snippet装饰器很方便 ,但是推荐使用注册snippets作为函数 在你的 wagtail_hooks.py 文件中,例如;</p> 
    <pre data-index="40" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># myapp/wagtail_hooks.py</span>
    from wagtail.snippets.models <span class="token function">import</span> register_snippet
    
    from myapp.models <span class="token function">import</span> Advert
    
    register_snippet<span class="token punctuation">(</span>Advert<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>以这种方式注册片段允许您稍后使用自定义的 SnippetViewSet 类进行进一步的自定义。这也提供了 Django 模型和 Wagtail 特定关注点之间的更好分离。例如,不是在模型类上定义面板或 edit_handler,而是可以在 SnippetViewSet 类上定义它们:<br> 这个定义好之后,通过数据迁移,即可在wagtail管理后台看到对应的菜单</p> 
    <pre data-index="41" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># myapp/wagtail_hooks.py</span>
    from wagtail.snippets.models <span class="token function">import</span> register_snippet
    from wagtail.snippets.views.snippets <span class="token function">import</span> SnippetViewSet
    
    from myapp.models <span class="token function">import</span> Advert
    
    
    class AdvertViewSet<span class="token punctuation">(</span>SnippetViewSet<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Advert
    
        panels <span class="token operator">=</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">"url"</span><span class="token punctuation">)</span>,
            FieldPanel<span class="token punctuation">(</span><span class="token string">"text"</span><span class="token punctuation">)</span>,
        <span class="token punctuation">]</span>
    
    <span class="token comment"># Instead of using @register_snippet as a decorator on the model class,</span>
    <span class="token comment"># register the snippet using register_snippet as a function and pass in</span>
    <span class="token comment"># the custom SnippetViewSet subclass.</span>
    register_snippet<span class="token punctuation">(</span>AdvertViewSet<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/5198f41a47719cee.png" alt="在这里插入图片描述"><br> 官方的帮助文档是按下面方式处理的</p> 
    <pre data-index="42" class="set-code-hide prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db import models
    
    from wagtail.admin.edit_handlers import FieldPanel
    from wagtail.snippets.models import register_snippet
    
    ...
    
    @register_snippet
    class Advert(models.Model):
        url = models.URLField(null=True, blank=True)
        text = models.CharField(max_length=255)
    
        panels = [
            FieldPanel('url'),
            FieldPanel('text'),
        ]
    
        def __str__(self):
            return self.text
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p>Advert model 使用了基本Django数据模型类 model class and defines two properties: text and URL. The editing interface is very close to that provided for Page-derived models, with fields assigned in the panels property. Snippets do not use multiple tabs of fields, nor do they provide the “save as draft” or “submit for moderation” features.</p> 
    <p>@register_snippet tells Wagtail to treat the model as a snippet. The panels list defines the fields to show on the snippet editing page. It’s also important to provide a string representation of the class through def <strong>str</strong>(self): so that the snippet objects make sense when listed in the Wagtail admin.</p> 
    <h3><a name="t35"></a><a id="_Snippets_1071"></a>绑定页面到 Snippets</h3> 
    <p>即在页面中引用这个片段。<br> <img src="https://1000bd.com/contentImg/2024/03/25/3cfa445d9ab84d0c.png" alt="在这里插入图片描述"></p> 
    <p>在上面的例子中,广告列表是一个固定的列表,它通过自定义模板标签显示,与页面上的任何其他内容无关。这对于侧边栏中的常见面板来说可能是您想要的,但是,在另一种情况下,您可能希望仅在特定页面上显示一个特定的代码片段实例。这可以通过在您的页面模型中定义对代码片段模型的外键并在页面的 content_panels 列表中添加一个 SnippetChooserPanel 来实现。例如,如果您想在 BookPage 实例上显示特定的广告:</p> 
    <pre data-index="43" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from wagtail.snippets.edit_handlers import SnippetChooserPanel
    # ...
    class BookPage(Page):
        advert = models.ForeignKey(
            'demo.Advert',
            null=True,
            blank=True,
            on_delete=models.SET_NULL,
            related_name='+'
        )
    
        content_panels = Page.content_panels + [
            SnippetChooserPanel('advert'),
            # ...
        ]
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li></ul></pre> 
    <p>然后,您可以在模板中通过 page.advert 访问该代码片段。</p> 
    <p>要将多个广告附加到页面,可以将 SnippetChooserPanel 放置在 BookPage 的内联子对象上,而不是 BookPage 本身。在这里,这个子模型被命名为 BookPageAdvertPlacement(之所以这样命名,是因为每次在 BookPage 上放置广告时都会有一个这样的对象)。</p> 
    <pre data-index="44" class="set-code-hide prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db import models
    
    from wagtail.core.models import Page, Orderable
    from wagtail.snippets.edit_handlers import SnippetChooserPanel
    
    from modelcluster.fields import ParentalKey
    
    ...
    
    class BookPageAdvertPlacement(Orderable, models.Model):
        page = ParentalKey('demo.BookPage', on_delete=models.CASCADE, related_name='advert_placements')
        advert = models.ForeignKey('demo.Advert', on_delete=models.CASCADE, related_name='+')
    
        class Meta(Orderable.Meta):
            verbose_name = "advert placement"
            verbose_name_plural = "advert placements"
    
        panels = [
            SnippetChooserPanel('advert'),
        ]
    
        def __str__(self):
            return self.page.title + " -> " + self.advert.text
    
    
    class BookPage(Page):
        ...
    
        content_panels = Page.content_panels + [
            InlinePanel('advert_placements', label="Adverts"),
            # ...
        ]
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li></ul></pre> 
    <p>These child objects are now accessible through the page’s advert_placements property, and from there we can access the linked Advert snippet as advert. In the template for BookPage, we could include the following:</p> 
    <pre data-index="45" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">{% for advert_placement in page.advert_placements.all %}
        <p>
            <a href="{<!-- -->{ advert_placement.advert.url }}">
                {<!-- -->{ advert_placement.advert.text }}
            </a>
        </p>
    {% endfor %}
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li></ul></pre> 
    <h2><a name="t36"></a><a id="_1145"></a>定制管理平台</h2> 
    <h3><a name="t37"></a><a id="_1146"></a>定制管理界面模板</h3> 
    <p>In your projects with Wagtail, you may wish to replace elements such as the Wagtail logo within the admin interface with your own branding. This can be done through Django’s template inheritance mechanism.</p> 
    <p>You need to create a templates/wagtailadmin/ folder within one of your apps - this may be an existing one, or a new one created for this purpose, for example, dashboard. This app must be registered in <code>INSTALLED_APPS</code> before wagtail.admin:</p> 
    <pre data-index="46" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">INSTALLED_APPS <span class="token operator">=</span> <span class="token punctuation">(</span>
        <span class="token comment"># ...</span>
    
        <span class="token string">'dashboard'</span>,
    
        <span class="token string">'wagtail'</span>,
        <span class="token string">'wagtail.admin'</span>,
    
        <span class="token comment"># ...</span>
    <span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li></ul></pre> 
    <h3><a name="t38"></a><a id="_1165"></a>定制品牌</h3> 
    <p>The template blocks that are available to customise the branding in the admin interface are as follows:</p> 
    <p>branding_logo<br> To replace the default logo, create a template file <code>dashboard/templates/wagtailadmin/base.html</code> that overrides the block branding_logo:</p> 
    <pre data-index="47" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">"wagtailadmin/base.html"</span> %<span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span>% load static %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block branding_logo %<span class="token punctuation">}</span>
        <span class="token operator"><</span>img <span class="token assign-left variable">src</span><span class="token operator">=</span><span class="token string">"{% static 'images/custom-logo.svg' %}"</span> <span class="token assign-left variable">alt</span><span class="token operator">=</span><span class="token string">"Custom Project"</span> <span class="token assign-left variable">width</span><span class="token operator">=</span><span class="token string">"80"</span> /<span class="token operator">></span>
    <span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>The logo also appears in the following pages and can be replaced with its template file:</p> 
    <p>login page - create a template file <code>dashboard/templates/wagtailadmin/login.html</code> that overwrites the branding_logo block.</p> 
    <p>404 error page - create a template file <code>dashboard/templates/wagtailadmin/404.html</code> that overrides the branding_logo block.</p> 
    <p>wagtail userbar - create a template file <code>dashboard/templates/wagtailadmin/userbar/base.html</code> that overwrites the branding_logo block.</p> 
    <p>branding_favicon<br> To replace the favicon displayed when viewing admin pages, create a template file dashboard/templates/wagtailadmin/admin_base.html that overrides the block branding_favicon:</p> 
    <pre data-index="48" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">"wagtailadmin/admin_base.html"</span> %<span class="token punctuation">}</span>
    <span class="token punctuation">{<!-- --></span>% load static %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block branding_favicon %<span class="token punctuation">}</span>
        <span class="token operator"><</span>link <span class="token assign-left variable">rel</span><span class="token operator">=</span><span class="token string">"shortcut icon"</span> <span class="token assign-left variable">href</span><span class="token operator">=</span><span class="token string">"{% static 'images/favicon.ico' %}"</span> /<span class="token operator">></span>
    <span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>branding_title<br> To replace the title prefix (which is ‘Wagtail’ by default), create a template file <code>dashboard/templates/wagtailadmin/admin_base.html</code> that overrides the block branding_title:</p> 
    <pre data-index="49" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">"wagtailadmin/admin_base.html"</span> %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block branding_title %<span class="token punctuation">}</span>Frank's CMS<span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre> 
    <h3><a name="t39"></a><a id="_1212"></a>定制登录界面</h3> 
    <p>To replace the login message, create a template file <code>dashboard/templates/wagtailadmin/login.html</code> that overrides the block branding_login:</p> 
    <pre data-index="50" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">"wagtailadmin/login.html"</span> %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block branding_login %<span class="token punctuation">}</span>Sign <span class="token keyword">in</span> to Frank's Site<span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre> 
    <h3><a name="t40"></a><a id="_1222"></a>定制欢迎界面</h3> 
    <p>To replace the welcome message on the dashboard, create a template file <code>dashboard/templates/wagtailadmin/home.html</code> that overrides the block branding_welcome:</p> 
    <pre data-index="51" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token punctuation">{<!-- --></span>% extends <span class="token string">"wagtailadmin/home.html"</span> %<span class="token punctuation">}</span>
    
    <span class="token punctuation">{<!-- --></span>% block branding_welcome %<span class="token punctuation">}</span>Welcome to Frank's Site<span class="token punctuation">{<!-- --></span>% endblock %<span class="token punctuation">}</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre> 
    <h3><a name="t41"></a><a id="_1231"></a>去掉登录界面下面图标</h3> 
    <p>找到虚拟环境安装的站点包,这个项目在这个位置<code>C:\djangoprj\Innovativewagprj\venv\Lib\site-packages\wagtail\admin\templates\wagtailadmin\login.html</code><br> 注释掉图标部分。<br> <img src="https://1000bd.com/contentImg/2024/03/25/24fa29132d7269db.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t42"></a><a id="_1236"></a>修改部分没有汉化的部分</h3> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/44f1b475255b1f62.png" alt="在这里插入图片描述"><br> 在snipset的小组件上有些地方会没有汉化,可以找到源码位置,如下面路径</p> 
    <p>/home/gsl/mysite/myvenv/lib/python3.10/site-packages/wagtail/snippets</p> 
    <pre data-index="52" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token function">sudo</span> <span class="token function">vi</span> widgets.py
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>替换这个位置<br> <img src="https://1000bd.com/contentImg/2024/03/25/3b6764e17024394a.png" alt="在这里插入图片描述"></p> 
    <h2><a name="t43"></a><a id="wagtaildjango_1250"></a>把wagtail集成到django项目</h2> 
    <h3><a name="t44"></a><a id="_1251"></a>安装插件</h3> 
    <pre data-index="53" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">$ pip install wagtail
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>安装后的内容</p> 
    <pre data-index="54" class="set-code-hide prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">
    <span class="token punctuation">(</span>venv<span class="token punctuation">)</span> C:\djangoprj\eshop>pip list
    Package             Version
    <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span> <span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">--</span><span class="token operator">-</span>
    anyascii            0<span class="token punctuation">.</span>2<span class="token punctuation">.</span>0
    asgiref             3<span class="token punctuation">.</span>3<span class="token punctuation">.</span>4
    beautifulsoup4      4<span class="token punctuation">.</span>9<span class="token punctuation">.</span>3
    certifi             2020<span class="token punctuation">.</span>12<span class="token punctuation">.</span>5
    chardet             4<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0
    Django              3<span class="token punctuation">.</span>2<span class="token punctuation">.</span>3
    django-cors-headers 3<span class="token punctuation">.</span>7<span class="token punctuation">.</span>0
    django-<span class="token keyword">filter</span>       2<span class="token punctuation">.</span>4<span class="token punctuation">.</span>0
    django-modelcluster 5<span class="token punctuation">.</span>1
    django-taggit       1<span class="token punctuation">.</span>4<span class="token punctuation">.</span>0
    django-tinymce      3<span class="token punctuation">.</span>3<span class="token punctuation">.</span>0
    django-treebeard    4<span class="token punctuation">.</span>5<span class="token punctuation">.</span>1
    djangorestframework 3<span class="token punctuation">.</span>12<span class="token punctuation">.</span>4
    draftjs-exporter    2<span class="token punctuation">.</span>1<span class="token punctuation">.</span>7
    et-xmlfile          1<span class="token punctuation">.</span>1<span class="token punctuation">.</span>0
    html5lib            1<span class="token punctuation">.</span>1
    idna                2<span class="token punctuation">.</span>10
    l18n                2020<span class="token punctuation">.</span>6<span class="token punctuation">.</span>1
    openpyxl            3<span class="token punctuation">.</span>0<span class="token punctuation">.</span>7
    Pillow              8<span class="token punctuation">.</span>2<span class="token punctuation">.</span>0
    pip                 21<span class="token punctuation">.</span>1<span class="token punctuation">.</span>2
    PyMySQL             1<span class="token punctuation">.</span>0<span class="token punctuation">.</span>2
    pytz                2021<span class="token punctuation">.</span>1
    requests            2<span class="token punctuation">.</span>25<span class="token punctuation">.</span>1
    setuptools          57<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0
    six                 1<span class="token punctuation">.</span>16<span class="token punctuation">.</span>0
    soupsieve           2<span class="token punctuation">.</span>2<span class="token punctuation">.</span>1
    sqlparse            0<span class="token punctuation">.</span>4<span class="token punctuation">.</span>1
    tablib              3<span class="token punctuation">.</span>0<span class="token punctuation">.</span>0
    telepath            0<span class="token punctuation">.</span>1<span class="token punctuation">.</span>1
    urllib3             1<span class="token punctuation">.</span>26<span class="token punctuation">.</span>5
    wagtail             2<span class="token punctuation">.</span>13
    webencodings        0<span class="token punctuation">.</span>5<span class="token punctuation">.</span>1
    Willow              1<span class="token punctuation">.</span>4
    xlrd                2<span class="token punctuation">.</span>0<span class="token punctuation">.</span>1
    XlsxWriter          1<span class="token punctuation">.</span>4<span class="token punctuation">.</span>3
    xlwt                1<span class="token punctuation">.</span>3<span class="token punctuation">.</span>0
    
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li></ul></pre> 
    <h3><a name="t45"></a><a id="Settings_1305"></a>Settings配置</h3> 
    <p>INSTALLED_APPS:</p> 
    <pre data-index="55" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token string">'wagtail.contrib.forms'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.contrib.redirects'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.embeds'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.sites'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.users'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.snippets'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.documents'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.images'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.search'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.admin'</span><span class="token punctuation">,</span>
    <span class="token string">'wagtail.core'</span><span class="token punctuation">,</span>
    
    <span class="token string">'modelcluster'</span><span class="token punctuation">,</span>
    <span class="token string">'taggit'</span><span class="token punctuation">,</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li></ul></pre> 
    <p>MIDDLEWARE:</p> 
    <pre data-index="56" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token string">'wagtail.contrib.redirects.middleware.RedirectMiddleware'</span><span class="token punctuation">,</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>Add a STATIC_ROOT setting, if your project does not have one already:</p> 
    <pre data-index="57" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">STATIC_ROOT = os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>BASE_DIR<span class="token punctuation">,</span> <span class="token string">'static'</span><span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>Add MEDIA_ROOT and MEDIA_URL settings, if your project does not have these already:</p> 
    <pre data-index="58" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">MEDIA_ROOT = os<span class="token punctuation">.</span>path<span class="token punctuation">.</span>join<span class="token punctuation">(</span>BASE_DIR<span class="token punctuation">,</span> <span class="token string">'media'</span><span class="token punctuation">)</span>
    MEDIA_URL = <span class="token string">'/media/'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre> 
    <p>Add a WAGTAIL_SITE_NAME - this will be displayed on the main dashboard of the Wagtail admin backend:</p> 
    <pre data-index="59" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;">WAGTAIL_SITE_NAME = <span class="token string">'My Example Site'</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>Various other settings are available to configure Wagtail’s behaviour - see Settings.</p> 
    <h3><a name="t46"></a><a id="URL_1351"></a>URL配置</h3> 
    <pre data-index="60" class="set-code-show prettyprint"><code class="prism language-powershell has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token keyword">from</span> django<span class="token punctuation">.</span>urls import path<span class="token punctuation">,</span> re_path<span class="token punctuation">,</span> include
    
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>admin import urls as wagtailadmin_urls
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>core import urls as wagtail_urls
    <span class="token keyword">from</span> wagtail<span class="token punctuation">.</span>documents import urls as wagtaildocs_urls
    
    urlpatterns = <span class="token punctuation">[</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
        path<span class="token punctuation">(</span><span class="token string">'cms/'</span><span class="token punctuation">,</span> include<span class="token punctuation">(</span>wagtailadmin_urls<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        path<span class="token punctuation">(</span><span class="token string">'documents/'</span><span class="token punctuation">,</span> include<span class="token punctuation">(</span>wagtaildocs_urls<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        path<span class="token punctuation">(</span><span class="token string">'pages/'</span><span class="token punctuation">,</span> include<span class="token punctuation">(</span>wagtail_urls<span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">,</span>
        <span class="token punctuation">.</span><span class="token punctuation">.</span><span class="token punctuation">.</span>
    <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li></ul></pre> 
    <p>wagtailadmin_urls provides the admin interface for Wagtail. This is separate from the Django admin interface (django.contrib.admin); Wagtail-only projects typically host the Wagtail admin at /admin/, but if this would clash with your project’s existing admin backend then an alternative path can be used, such as /cms/ here.</p> 
    <p>wagtaildocs_urls is the location from where document files will be served. This can be omitted if you do not intend to use Wagtail’s document management features.</p> 
    <p>wagtail_urls is the base location from where the pages of your Wagtail site will be served. In the above example, Wagtail will handle URLs under /pages/, leaving the root URL and other paths to be handled as normal by your Django project. If you want Wagtail to handle the entire URL space including the root URL, this can be replaced with:</p> 
    <h2><a name="t47"></a><a id="_1375"></a>错误</h2> 
    <p>报错如下,可能是Pillow的版本不对,降低下版本即可。</p> 
    <pre data-index="61" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">wagtailusers.UserProfile.avatar: (fields.E210) Cannot use ImageField because Pillow is not installed.
            HINT: Get Pillow at https://pypi.org/project/Pillow/ or run command "python -m pip install Pillow".
    
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre> 
    <pre data-index="62" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">(venv) C:\djangoprj\hotlinewag>pip uninstall Pillow
    Found existing installation: Pillow 8.3.0
    Uninstalling Pillow-8.3.0:
      Would remove:
        c:\djangoprj\hotlinewag\venv\lib\site-packages\pil\*
        c:\djangoprj\hotlinewag\venv\lib\site-packages\pillow-8.3.0.dist-info\*
    Proceed (y/n)? y
      Successfully uninstalled Pillow-8.3.0
    
    (venv) C:\djangoprj\hotlinewag>pip install Pillow==8.2.0
    Collecting Pillow==8.2.0
      Using cached Pillow-8.2.0-cp38-cp38-win_amd64.whl (2.2 MB)
    Installing collected packages: Pillow
    Successfully installed Pillow-8.2.0
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li></ul></pre> 
    <h2><a name="t48"></a><a id="wagtailapi_1403"></a>wagtail的api</h2> 
    <h3><a name="t49"></a><a id="_1404"></a>基本配置</h3> 
    <h4><a name="t50"></a><a id="app_1405"></a>使能app</h4> 
    <p>在配置文件中加入api应用</p> 
    <pre data-index="63" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># settings.py</span>
    
    INSTALLED_APPS <span class="token operator">=</span> <span class="token punctuation">[</span>
        <span class="token punctuation">..</span>.
    
        <span class="token string">'wagtail.api.v2'</span>,
    
        <span class="token punctuation">..</span>.
    <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li></ul></pre> 
    <p>可选的,通过添加<strong>rest_framework</strong> 到 <strong>INSTALLED_APPS.</strong> 可以通过浏览器来查看api,如果是基本的json格式输出是不必须的。</p> 
    <h4><a name="t51"></a><a id="endpoints_1420"></a>配置endpoints</h4> 
    <p>下面配置那些内容暴露到API。每种内容类型有对应的endpoint。endpoint结合路由,通过url配置连接项目的其他部分。<br> 三种endpoint</p> 
    <pre data-index="64" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">Pages wagtail.api.v2.views.PagesAPIViewSet
    Images wagtail.images.api.v2.views.ImagesAPIViewSet
    Documents wagtail.documents.api.v2.views.DocumentsAPIViewSet
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre> 
    <p>可以继承他们定制自己的类。也可以从基础类派生</p> 
    <pre data-index="65" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"> wagtail.api.v2.views.BaseAPIViewSet
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>在项目目录新建一个文件api.py<br> <img src="https://1000bd.com/contentImg/2024/03/25/bc0bb4f714387b39.png" alt="在这里插入图片描述"></p> 
    <pre data-index="66" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># api.py</span>
    
    from wagtail.api.v2.views <span class="token function">import</span> PagesAPIViewSet
    from wagtail.api.v2.router <span class="token function">import</span> WagtailAPIRouter
    from wagtail.images.api.v2.views <span class="token function">import</span> ImagesAPIViewSet
    from wagtail.documents.api.v2.views <span class="token function">import</span> DocumentsAPIViewSet
    
    <span class="token comment"># Create the router. "wagtailapi" is the URL namespace</span>
    api_router <span class="token operator">=</span> WagtailAPIRouter<span class="token punctuation">(</span><span class="token string">'wagtailapi'</span><span class="token punctuation">)</span>
    
    <span class="token comment"># Add the three endpoints using the "register_endpoint" method.</span>
    <span class="token comment"># The first parameter is the name of the endpoint (eg. pages, images). This</span>
    <span class="token comment"># is used in the URL of the endpoint</span>
    <span class="token comment"># The second parameter is the endpoint class that handles the requests</span>
    api_router.register_endpoint<span class="token punctuation">(</span><span class="token string">'pages'</span>, PagesAPIViewSet<span class="token punctuation">)</span>
    api_router.register_endpoint<span class="token punctuation">(</span><span class="token string">'images'</span>, ImagesAPIViewSet<span class="token punctuation">)</span>
    api_router.register_endpoint<span class="token punctuation">(</span><span class="token string">'documents'</span>, DocumentsAPIViewSet<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li></ul></pre> 
    <h4><a name="t52"></a><a id="url_1460"></a>注册url</h4> 
    <p>注册url,使Django能够路由请求道API。</p> 
    <pre data-index="67" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># urls.py</span>
    
    from .api <span class="token function">import</span> api_router
    
    urlpatterns <span class="token operator">=</span> <span class="token punctuation">[</span>
        <span class="token punctuation">..</span>.
    
        path<span class="token punctuation">(</span><span class="token string">'api/v2/'</span>, api_router.urls<span class="token punctuation">)</span>,
    
        <span class="token punctuation">..</span>.
    
        <span class="token comment"># 确保api_route.urls 必须在wagtail_urls之前。</span>
        re_path<span class="token punctuation">(</span>r<span class="token string">'^'</span>, include<span class="token punctuation">(</span>wagtail_urls<span class="token punctuation">))</span>,
    <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li></ul></pre> 
    <h3><a name="t53"></a><a id="api_1480"></a>访问api</h3> 
    <p>通过以上配置,可以访问pages通过 /api/v2/pages/, images 通过 /api/v2/images/ 和 documents 通过 /api/v2/documents/<br> 所有页面<br> <img src="https://1000bd.com/contentImg/2024/03/25/5c748d4477a0d69c.png" alt="在这里插入图片描述"><br> 单个一面<br> <img src="https://1000bd.com/contentImg/2024/03/25/87b43f6b43a9f565.png" alt="在这里插入图片描述"></p> 
    <p>图像、文档同样<br> <img src="https://1000bd.com/contentImg/2024/03/25/80bc2d9815449da8.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t54"></a><a id="_1492"></a>使字段能够访问</h3> 
    <p>从上面看到,不是所有的页面的定制字段都能够通过API访问到,实现这一点,可以通过添加字段列表到api_fields属性来实现。</p> 
    <pre data-index="68" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># models.py</span>
    
    from wagtail.api <span class="token function">import</span> APIField
    
    class BlogPageAuthor<span class="token punctuation">(</span>Orderable<span class="token punctuation">)</span>:
        page <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span><span class="token string">'blog.BlogPage'</span>, <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'authors'</span><span class="token punctuation">)</span>
        name <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
    
        api_fields <span class="token operator">=</span> <span class="token punctuation">[</span>
            APIField<span class="token punctuation">(</span><span class="token string">'name'</span><span class="token punctuation">)</span>,
        <span class="token punctuation">]</span>
    
    
    class BlogPage<span class="token punctuation">(</span>Page<span class="token punctuation">)</span>:
        published_date <span class="token operator">=</span> models.DateTimeField<span class="token punctuation">(</span><span class="token punctuation">)</span>
        body <span class="token operator">=</span> RichTextField<span class="token punctuation">(</span><span class="token punctuation">)</span>
        feed_image <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span><span class="token string">'wagtailimages.Image'</span>, <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.SET_NULL, <span class="token assign-left variable">null</span><span class="token operator">=</span>True, <span class="token punctuation">..</span>.<span class="token punctuation">)</span>
        private_field <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
    
        <span class="token comment"># Export fields over the API</span>
        api_fields <span class="token operator">=</span> <span class="token punctuation">[</span>
            APIField<span class="token punctuation">(</span><span class="token string">'published_date'</span><span class="token punctuation">)</span>,
            APIField<span class="token punctuation">(</span><span class="token string">'body'</span><span class="token punctuation">)</span>,
            APIField<span class="token punctuation">(</span><span class="token string">'feed_image'</span><span class="token punctuation">)</span>,
            APIField<span class="token punctuation">(</span><span class="token string">'authors'</span><span class="token punctuation">)</span>,  <span class="token comment"># This will nest the relevant BlogPageAuthor objects in the API response</span>
        <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li></ul></pre> 
    <p>在models增加导入,</p> 
    <pre data-index="69" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from wagtail.api <span class="token function">import</span> APIField
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>在APIField中加入需要暴露的字段,各种类型字段都可以。</p> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/e8957e33801c2e9c.png" alt="在这里插入图片描述"></p> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/8df568b96620a4a4.png" alt="在这里插入图片描述"><br> 图片的详细链接<br> <img src="https://1000bd.com/contentImg/2024/03/25/cffaab2b16d44fab.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t55"></a><a id="_1536"></a>按类型获取</h3> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/1a1447b86911d886.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t56"></a><a id="_1538"></a>限制获取的字段</h3> 
    <p>可以获取指定的字段,包含在嵌套中的字段。<br> <img src="https://1000bd.com/contentImg/2024/03/25/250ab241714c5e83.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t57"></a><a id="_1541"></a>限制获取数量</h3> 
    <p>分页使用,每页显示数量。<br> <img src="https://1000bd.com/contentImg/2024/03/25/98f2058406a830fe.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t58"></a><a id="_1544"></a>偏移量实现分页获取</h3> 
    <p>偏移量指出了每次获取记录的第一条在总记录的中的位置,第一个位置的偏移量是0,这样利用<strong>偏移量+每页条数</strong>可以分页获取。<br> <img src="https://1000bd.com/contentImg/2024/03/25/0c7bda4f6d604677.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t59"></a><a id="_1547"></a>排序</h3> 
    <p>字母顺序<br> <img src="https://1000bd.com/contentImg/2024/03/25/36124f4a957fde69.png" alt="在这里插入图片描述"></p> 
    <p>order=-title将获得反向排序。</p> 
    <h3><a name="t60"></a><a id="_1553"></a>获得子页面</h3> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/833a01aaac5ad1ed.png" alt="在这里插入图片描述"></p> 
    <p>有个问题,获取子页面,没法获取子页面上的image,所以没法按索引页面和它的子页面来分类获取</p> 
    <h3><a name="t61"></a><a id="_1557"></a>分类获取数据</h3> 
    <p>发现wagtail只能通过page的type来获取数据时候,才能获取到更多的数据,如果是获得子页面的方法获得的分类数据,就没法获取更多深层次数据,所以需要在页面中增加一个分类字段,通过页面类型和分类字段获取image</p> 
    <pre data-index="70" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">http://localhost:8000/api/v2/pages/?type<span class="token operator">=</span>blog.BlogPage<span class="token operator">&</span><span class="token assign-left variable">open_type</span><span class="token operator">=</span>switchTab<span class="token operator">&</span><span class="token assign-left variable">fields</span><span class="token operator">=</span>image,open_type
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>其中type=blog.BlogPage指定获取的页面类型,没有这个前提,没法获取详细页面数据;open_type=switchTab是自定义的页面分类依据字段,通过这个字段获取到相同分类的页面;fields=image,open_type定义了需要详细显示的字段,没有可能是不显示的。当然api暴露也是要有的。</p> 
    <h3><a name="t62"></a><a id="orderable_1564"></a>获取orderable数据</h3> 
    <p>把需要暴露的orderable添加到APIfield<br> <img src="https://1000bd.com/contentImg/2024/03/25/3a9dc14cb095fcae.png" alt="在这里插入图片描述"><br> 在orderable中添加需要暴露的字段到APIfiled<br> <img src="https://1000bd.com/contentImg/2024/03/25/df0d477574e6a86b.png" alt="在这里插入图片描述"></p> 
    <h4><a name="t63"></a><a id="orderable_1569"></a>只查询orderable的数据</h4> 
    <pre data-index="71" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">http://192.168.2.21/api/v2/pages/3/?fields<span class="token operator">=</span>_,mycarousel
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/2433fb8a7526d823.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t64"></a><a id="StreamField_imageurl_1576"></a>获取StreamField 中的image的url</h3> 
    <p>通常的方法只能获得StreamField 中图片的id,不能满足需要,做一下改动<br> page中引用的StreamField 如下</p> 
    <pre data-index="72" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from streams.blocks <span class="token function">import</span> BaseStreamBlock
    。。。
    
        body <span class="token operator">=</span> StreamField<span class="token punctuation">(</span>
            BaseStreamBlock<span class="token punctuation">(</span><span class="token punctuation">)</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">"Page body"</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True
    。。。
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <p>blocks中的BaseStreamBlock</p> 
    <pre data-index="73" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># 原有的导入</span>
    <span class="token comment"># from wagtail.images.blocks import ImageChooserBlock</span>
    <span class="token comment"># 增加的导入</span>
    from wagtail.images.blocks <span class="token function">import</span> ImageChooserBlock as DefaultImageChooserBlock
    
    
    <span class="token comment"># 增加的定义</span>
    class ImageChooserBlock<span class="token punctuation">(</span>DefaultImageChooserBlock<span class="token punctuation">)</span>:
        def get_api_representation<span class="token punctuation">(</span>self, value, <span class="token assign-left variable">context</span><span class="token operator">=</span>None<span class="token punctuation">)</span>:
            <span class="token keyword">if</span> value:
                <span class="token builtin class-name">return</span> <span class="token punctuation">{<!-- --></span>
                    <span class="token string">'id'</span><span class="token builtin class-name">:</span> value.id,
                    <span class="token string">'title'</span><span class="token builtin class-name">:</span> value.title,
                    <span class="token string">'large'</span><span class="token builtin class-name">:</span> value.get_rendition<span class="token punctuation">(</span><span class="token string">'width-1000'</span><span class="token punctuation">)</span>.attrs_dict,
                    <span class="token string">'mobile'</span><span class="token builtin class-name">:</span> value.get_rendition<span class="token punctuation">(</span><span class="token string">'width-320'</span><span class="token punctuation">)</span>.attrs_dict,
                    <span class="token string">'thumbnail'</span><span class="token builtin class-name">:</span> value.get_rendition<span class="token punctuation">(</span><span class="token string">'fill-120x120'</span><span class="token punctuation">)</span>.attrs_dict,
                <span class="token punctuation">}</span>
    
    <span class="token comment"># 原有的结构</span>
    class ImageBlock<span class="token punctuation">(</span>StructBlock<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        Custom <span class="token variable"><span class="token variable">`</span>StructBlock<span class="token variable">`</span></span> <span class="token keyword">for</span> utilizing images with associated caption and
        attribution data
        <span class="token string">""</span>"
        image <span class="token operator">=</span> ImageChooserBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>True<span class="token punctuation">)</span>
        caption <span class="token operator">=</span> CharBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>False<span class="token punctuation">)</span>
        attribution <span class="token operator">=</span> CharBlock<span class="token punctuation">(</span>required<span class="token operator">=</span>False<span class="token punctuation">)</span>
    
        class Meta:
            icon <span class="token operator">=</span> <span class="token string">'image'</span>
            template <span class="token operator">=</span> <span class="token string">"blocks/image_block.html"</span>
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li></ul></pre> 
    <p>相当于重写了get_api_representation,可以灵活定义图片的大小。<br> 返回结果<br> <img src="https://1000bd.com/contentImg/2024/03/25/3bf6eddafa4aa8bf.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t65"></a><a id="_1629"></a>表单</h3> 
    <pre data-index="74" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">https://stackoverflow.com/questions/61289214/wagtail-form-file-upload
    
    https://github.com/spapas/wagtail-multi-upload
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li></ul></pre> 
    <h2><a name="t66"></a><a id="models_1637"></a>models的序列化</h2> 
    <p>对于无法获取的api展现的库表可以采用drf的序列化方法</p> 
    <h3><a name="t67"></a><a id="models_1639"></a>一般models序列化</h3> 
    <p>按drf要求即可,看参考django的文章<br> 需要配置url,view,和serializers的py文件</p> 
    <p>serializers.py</p> 
    <pre data-index="75" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">
    from rest_framework <span class="token function">import</span> serializers
    from base.blocks <span class="token function">import</span> Country
    from home.models <span class="token function">import</span> Category
    from wagtail.images.models <span class="token function">import</span> Image
    
    class CountrySerializer<span class="token punctuation">(</span>serializers.ModelSerializer<span class="token punctuation">)</span>:
        class Meta:
            model <span class="token operator">=</span> Country
            fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'id'</span>, <span class="token string">'title'</span>,<span class="token punctuation">)</span>
    
    
    class MyImageSerializer<span class="token punctuation">(</span>serializers.ModelSerializer<span class="token punctuation">)</span>:
        class Meta:
            model <span class="token operator">=</span>  Image
            fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'id'</span>, <span class="token string">'title'</span>,<span class="token string">'file'</span>,<span class="token punctuation">)</span>
    
    class CategorySerializer<span class="token punctuation">(</span>serializers.ModelSerializer<span class="token punctuation">)</span>:
        cxcategory <span class="token operator">=</span> CountrySerializer<span class="token punctuation">(</span><span class="token punctuation">)</span>
        image <span class="token operator">=</span> MyImageSerializer<span class="token punctuation">(</span><span class="token punctuation">)</span>
        class Meta:
            model <span class="token operator">=</span> Category
            fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'id'</span>, <span class="token string">'title'</span>, <span class="token string">'image'</span>, <span class="token string">'cxcategory'</span>,<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li></ul></pre> 
    <p>urls.py</p> 
    <pre data-index="76" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.urls <span class="token function">import</span> path
    from rest_framework.urlpatterns <span class="token function">import</span> format_suffix_patterns
    from home <span class="token function">import</span> views
    
    
    urlpatterns <span class="token operator">=</span> <span class="token punctuation">[</span>
        path<span class="token punctuation">(</span><span class="token string">'CategoryLIst/'</span>, views.CategoryListView.as_view<span class="token punctuation">(</span><span class="token punctuation">))</span>,
    <span class="token punctuation">]</span>
    
    urlpatterns <span class="token operator">=</span> format_suffix_patterns<span class="token punctuation">(</span>urlpatterns<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li></ul></pre> 
    <p>views.py</p> 
    <pre data-index="77" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from rest_framework <span class="token function">import</span> generics
    from rest_framework <span class="token function">import</span> permissions
    from rest_framework.authtoken.admin <span class="token function">import</span> User
    from rest_framework.pagination <span class="token function">import</span> LimitOffsetPagination, PageNumberPagination
    from home.models <span class="token function">import</span> Category
    from home.serializers <span class="token function">import</span> CategorySerializer
    <span class="token function">import</span> os
    from django.conf <span class="token function">import</span> settings
    from django.http <span class="token function">import</span> JsonResponse
    from django.utils <span class="token function">import</span> timezone
    from django.views.decorators.csrf <span class="token function">import</span> csrf_exempt
    
    
    class CategoryListView<span class="token punctuation">(</span>generics.ListAPIView<span class="token punctuation">)</span>:
        <span class="token string">''</span>'分类导航图标列表<span class="token string">''</span>'
        serializer_class <span class="token operator">=</span> CategorySerializer
        permissin_classes <span class="token operator">=</span> <span class="token punctuation">(</span>permissions.AllowAny,<span class="token punctuation">)</span>
        pagination_class <span class="token operator">=</span> LimitOffsetPagination  <span class="token comment"># 分页 请求加 ?limit = xx</span>
    
        def get_queryset<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
            <span class="token comment"># user = self.request.user</span>
            queryset <span class="token operator">=</span> Category.objects.all<span class="token punctuation">(</span><span class="token punctuation">)</span>
            <span class="token builtin class-name">return</span> queryset
    
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li></ul></pre> 
    <h3><a name="t68"></a><a id="model_1711"></a>内置model序列化</h3> 
    <p>查到model名字<br> 比如wagtail.images.models<img src="https://1000bd.com/contentImg/2024/03/25/5a2934cf4895265c.png" alt="在这里插入图片描述"><br> 从下面定制示例可知是image</p> 
    <pre data-index="78" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># models.py</span>
    from django.db <span class="token function">import</span> models
    
    from wagtail.images.models <span class="token function">import</span> Image, AbstractImage, AbstractRendition
    
    
    class CustomImage<span class="token punctuation">(</span>AbstractImage<span class="token punctuation">)</span>:
        <span class="token comment"># Add any extra fields to image here</span>
    
        <span class="token comment"># To add a caption field:</span>
        <span class="token comment"># caption = models.CharField(max_length=255, blank=True)</span>
    
        admin_form_fields <span class="token operator">=</span> Image.admin_form_fields + <span class="token punctuation">(</span>
            <span class="token comment"># Then add the field names here to make them appear in the form:</span>
            <span class="token comment"># 'caption',</span>
        <span class="token punctuation">)</span>
    
    
    class CustomRendition<span class="token punctuation">(</span>AbstractRendition<span class="token punctuation">)</span>:
        image <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span>CustomImage, <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'renditions'</span><span class="token punctuation">)</span>
    
        class Meta:
            unique_together <span class="token operator">=</span> <span class="token punctuation">(</span>
                <span class="token punctuation">(</span><span class="token string">'image'</span>, <span class="token string">'filter_spec'</span>, <span class="token string">'focal_point_key'</span><span class="token punctuation">)</span>,
            <span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li></ul></pre> 
    <p>然后可以这样进行serializers</p> 
    <pre data-index="79" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">class MyImageSerializer<span class="token punctuation">(</span>serializers.ModelSerializer<span class="token punctuation">)</span>:
        class Meta:
            model <span class="token operator">=</span>  Image
            fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'id'</span>, <span class="token string">'title'</span>,<span class="token string">'file'</span>,<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre> 
    <h2><a name="t69"></a><a id="Django_1751"></a>Django数据模型的纳管</h2> 
    <p>Wagtail 的数据模型管理类和Django的是不同的,虽然有相同的名字和实现相同的功能,但还是有些不同。添加和编辑表单仍然通过panels和edit_handlers来实现。<br> 在Wagtail中控制那些字段显示或可编辑在数据模型中,以及如何分组和排序,不管你的数据模型是页类型或片段或是标准的django模型。 Wagtail’s ModelAdmin 类更多的关心列表配置。例如,列表显示,列表过滤,搜索字段类似与Django,同时字段,字段设置,排除等其他属性是wagtail不支持的。</p> 
    <h3><a name="t70"></a><a id="_1756"></a>配置</h3> 
    <p>添加 wagtail.contrib.modeladmin to your INSTALLED_APPS:</p> 
    <pre data-index="80" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">INSTALLED_APPS <span class="token operator">=</span> <span class="token punctuation">[</span>
       <span class="token punctuation">..</span>.
       <span class="token string">'wagtail.contrib.modeladmin'</span>,
    <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre> 
    <h3><a name="t71"></a><a id="_1766"></a>使用</h3> 
    <p>可以定义普通的Django 模型,然后用ModelAdmin创建一个菜单来查看和编辑这个模型。</p> 
    <p>models.py looks like this:</p> 
    <pre data-index="81" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db <span class="token function">import</span> models
    from wagtail.admin.edit_handlers <span class="token function">import</span> FieldPanel
    from wagtail.images.edit_handlers <span class="token function">import</span> ImageChooserPanel
    
    class Book<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        title <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
        author <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">255</span><span class="token punctuation">)</span>
        cover_photo <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span>
            <span class="token string">'wagtailimages.Image'</span>,
            <span class="token assign-left variable">null</span><span class="token operator">=</span>True, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True,
            <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.SET_NULL,
            <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'+'</span>
        <span class="token punctuation">)</span>
    
        panels <span class="token operator">=</span> <span class="token punctuation">[</span>
            FieldPanel<span class="token punctuation">(</span><span class="token string">'title'</span><span class="token punctuation">)</span>,
            FieldPanel<span class="token punctuation">(</span><span class="token string">'author'</span><span class="token punctuation">)</span>,
            ImageChooserPanel<span class="token punctuation">(</span><span class="token string">'cover_photo'</span><span class="token punctuation">)</span>
        <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p>You can specify FieldPanels like ImageChooserPanel, PageChooserPanel, and DocumentChooserPanel within the panels attribute of the model. This lets you use Wagtail-specific features in an otherwise traditional Django model.</p> 
    <p>创建wagtail_hooks.py in your app directory would look something like this:<br> 也可以利用admin.py文件。在其中录入以下内容。</p> 
    <pre data-index="82" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from wagtail.contrib.modeladmin.options <span class="token function">import</span> <span class="token punctuation">(</span>
        ModelAdmin, modeladmin_register<span class="token punctuation">)</span>
    from .models <span class="token function">import</span> Book
    
    
    class BookAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Book
        menu_label <span class="token operator">=</span> <span class="token string">'Book'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'pilcrow'</span>  <span class="token comment"># change as required</span>
        menu_order <span class="token operator">=</span> <span class="token number">200</span>  <span class="token comment"># will put in 3rd place (000 being 1st, 100 2nd)</span>
        add_to_settings_menu <span class="token operator">=</span> False  <span class="token comment"># or True to add your model to the Settings sub-menu</span>
        exclude_from_explorer <span class="token operator">=</span> False <span class="token comment"># or True to exclude pages of this type from Wagtail's explorer view</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'title'</span>, <span class="token string">'author'</span><span class="token punctuation">)</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'author'</span>,<span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'title'</span>, <span class="token string">'author'</span><span class="token punctuation">)</span>
    
    <span class="token comment"># Now you just need to register your customised ModelAdmin class with Wagtail</span>
    modeladmin_register<span class="token punctuation">(</span>BookAdmin<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li></ul></pre> 
    <p>实际的例子:<br> models.py</p> 
    <pre data-index="83" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.db <span class="token function">import</span> models
    
    <span class="token comment"># 图片上传模型</span>
    class Image<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        eventID <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'事件id'</span><span class="token punctuation">)</span>
        images <span class="token operator">=</span> models.ImageField<span class="token punctuation">(</span>upload_to<span class="token operator">=</span><span class="token string">'images/uploads/%Y/%m/%d/'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
    
    <span class="token comment"># 投诉类数据模型</span>
    class ComplainFirstCategory<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        投诉一级类别
        <span class="token string">""</span>"
        name <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'名称'</span><span class="token punctuation">)</span>
    
        class Meta:
            verbose_name <span class="token operator">=</span> <span class="token string">'投诉一级类别'</span>
            verbose_name_plural <span class="token operator">=</span> verbose_name
    
        def __str__<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
            <span class="token builtin class-name">return</span> self.name  <span class="token comment"># 被引用时返回的值</span>
    
    
    class ComplainSecondCategory<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        投诉二级类别
        <span class="token string">""</span>"
        name <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'名称'</span><span class="token punctuation">)</span>
        ComplainFirstCategory <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span>ComplainFirstCategory, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'CompSecondCate'</span>,
                                                  <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'类别'</span><span class="token punctuation">)</span>
    
        class Meta:
            verbose_name <span class="token operator">=</span> <span class="token string">'投诉二级类别'</span>
            verbose_name_plural <span class="token operator">=</span> verbose_name
    
        def __str__<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
            <span class="token builtin class-name">return</span> self.name  <span class="token comment"># 被引用时返回的值</span>
    
    
    class Complain<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        投诉
        <span class="token string">""</span>"
        eventID <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'Id'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        title <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'标题'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        telnum <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'联系人电话'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        address <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>max_length<span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'事件地点'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        contents <span class="token operator">=</span> models.TextField<span class="token punctuation">(</span>verbose_name<span class="token operator">=</span><span class="token string">'投诉内容'</span><span class="token punctuation">)</span>
        ComplainFirstCategory <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span>ComplainFirstCategory, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'CompFirstCate'</span>,
                                                  <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'类别'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        ComplainSecondCategory <span class="token operator">=</span> models.ForeignKey<span class="token punctuation">(</span>ComplainSecondCategory, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'CompSecondCate'</span>,
                                                   <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'类别'</span>, <span class="token assign-left variable">blank</span><span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True<span class="token punctuation">)</span>
        created <span class="token operator">=</span> models.DateTimeField<span class="token punctuation">(</span>auto_now_add<span class="token operator">=</span>True<span class="token punctuation">)</span>
    
        class Meta:
            verbose_name <span class="token operator">=</span> <span class="token string">'投诉'</span>
            verbose_name_plural <span class="token operator">=</span> verbose_name
    
        def __str__<span class="token punctuation">(</span>self<span class="token punctuation">)</span>:
            <span class="token builtin class-name">return</span> self.title
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li><li style="color: rgb(153, 153, 153);">43</li><li style="color: rgb(153, 153, 153);">44</li><li style="color: rgb(153, 153, 153);">45</li><li style="color: rgb(153, 153, 153);">46</li><li style="color: rgb(153, 153, 153);">47</li><li style="color: rgb(153, 153, 153);">48</li><li style="color: rgb(153, 153, 153);">49</li><li style="color: rgb(153, 153, 153);">50</li><li style="color: rgb(153, 153, 153);">51</li><li style="color: rgb(153, 153, 153);">52</li><li style="color: rgb(153, 153, 153);">53</li><li style="color: rgb(153, 153, 153);">54</li><li style="color: rgb(153, 153, 153);">55</li><li style="color: rgb(153, 153, 153);">56</li><li style="color: rgb(153, 153, 153);">57</li><li style="color: rgb(153, 153, 153);">58</li><li style="color: rgb(153, 153, 153);">59</li><li style="color: rgb(153, 153, 153);">60</li></ul></pre> 
    <p>admin.py</p> 
    <pre data-index="84" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># Register your models here.</span>
    from wagtail.contrib.modeladmin.options <span class="token function">import</span> <span class="token punctuation">(</span>
        ModelAdmin, modeladmin_register<span class="token punctuation">)</span>
    <span class="token comment"># import imageuploadapps</span>
    from .models <span class="token function">import</span> Image
    
    class ImageAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Image
        menu_label <span class="token operator">=</span> <span class="token string">'Image'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'placeholder'</span>  <span class="token comment"># change as required</span>
        menu_order <span class="token operator">=</span> <span class="token number">200</span>  <span class="token comment"># will put in 3rd place (000 being 1st, 100 2nd)</span>
        add_to_settings_menu <span class="token operator">=</span> False  <span class="token comment"># or True to add your model to the Settings sub-menu</span>
        exclude_from_explorer <span class="token operator">=</span> False <span class="token comment"># or True to exclude pages of this type from Wagtail's explorer view</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'eventID'</span>, <span class="token string">'images'</span><span class="token punctuation">)</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'eventID'</span>,<span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'title'</span>, <span class="token string">'images'</span><span class="token punctuation">)</span>
    
    <span class="token comment"># Now you just need to register your customised ModelAdmin class with Wagtail</span>
    modeladmin_register<span class="token punctuation">(</span>ImageAdmin<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p>管理平台显示这样:<br> <img src="https://1000bd.com/contentImg/2024/03/25/2aa665c8055045c1.png" alt="在这里插入图片描述"></p> 
    <h3><a name="t72"></a><a id="_1909"></a>更为复杂些的例子</h3> 
    <p>假设你定义了Book, Author, and Genre 模型在models.py.<br> 你的app目录的admins.py 像这样:</p> 
    <pre data-index="85" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from wagtail.contrib.modeladmin.options <span class="token function">import</span> <span class="token punctuation">(</span>
        ModelAdmin, ModelAdminGroup, modeladmin_register<span class="token punctuation">)</span>
    from .models <span class="token function">import</span> <span class="token punctuation">(</span>
        Book, Author, Genre<span class="token punctuation">)</span>
    
    
    class BookAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Book
        menu_label <span class="token operator">=</span> <span class="token string">'Book'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'pilcrow'</span>  <span class="token comment"># change as required</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'title'</span>, <span class="token string">'author'</span><span class="token punctuation">)</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'genre'</span>, <span class="token string">'author'</span><span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'title'</span>, <span class="token string">'author'</span><span class="token punctuation">)</span>
    
    
    class AuthorAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Author
        menu_label <span class="token operator">=</span> <span class="token string">'Author'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'user'</span>  <span class="token comment"># change as required</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'first_name'</span>, <span class="token string">'last_name'</span><span class="token punctuation">)</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'first_name'</span>, <span class="token string">'last_name'</span><span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'first_name'</span>, <span class="token string">'last_name'</span><span class="token punctuation">)</span>
    
    
    class GenreAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> Genre
        menu_label <span class="token operator">=</span> <span class="token string">'Genre'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'group'</span>  <span class="token comment"># change as required</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'name'</span>,<span class="token punctuation">)</span>       <span class="token comment"># 单个字段需要后面加逗号。</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'name'</span>,<span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'name'</span>,<span class="token punctuation">)</span>
    
    
    class LibraryGroup<span class="token punctuation">(</span>ModelAdminGroup<span class="token punctuation">)</span>:       <span class="token comment">#制作一个菜单组,三个数据模型放在一起</span>
        menu_label <span class="token operator">=</span> <span class="token string">'Library'</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'folder-open-inverse'</span>  <span class="token comment"># change as required</span>
        menu_order <span class="token operator">=</span> <span class="token number">200</span>  <span class="token comment"># will put in 3rd place (000 being 1st, 100 2nd)</span>
        items <span class="token operator">=</span> <span class="token punctuation">(</span>BookAdmin, AuthorAdmin, GenreAdmin<span class="token punctuation">)</span>
    
    <span class="token comment"># When using a ModelAdminGroup class to group several ModelAdmin classes together,</span>
    <span class="token comment"># you only need to register the ModelAdminGroup class with Wagtail:</span>
    modeladmin_register<span class="token punctuation">(</span>LibraryGroup<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li><li style="color: rgb(153, 153, 153);">20</li><li style="color: rgb(153, 153, 153);">21</li><li style="color: rgb(153, 153, 153);">22</li><li style="color: rgb(153, 153, 153);">23</li><li style="color: rgb(153, 153, 153);">24</li><li style="color: rgb(153, 153, 153);">25</li><li style="color: rgb(153, 153, 153);">26</li><li style="color: rgb(153, 153, 153);">27</li><li style="color: rgb(153, 153, 153);">28</li><li style="color: rgb(153, 153, 153);">29</li><li style="color: rgb(153, 153, 153);">30</li><li style="color: rgb(153, 153, 153);">31</li><li style="color: rgb(153, 153, 153);">32</li><li style="color: rgb(153, 153, 153);">33</li><li style="color: rgb(153, 153, 153);">34</li><li style="color: rgb(153, 153, 153);">35</li><li style="color: rgb(153, 153, 153);">36</li><li style="color: rgb(153, 153, 153);">37</li><li style="color: rgb(153, 153, 153);">38</li><li style="color: rgb(153, 153, 153);">39</li><li style="color: rgb(153, 153, 153);">40</li><li style="color: rgb(153, 153, 153);">41</li><li style="color: rgb(153, 153, 153);">42</li></ul></pre> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/6fe11884ccc92e21.png" alt="在这里插入图片描述"></p> 
    <h2><a name="t73"></a><a id="Django_1962"></a>增加Django数据模型的用户档案</h2> 
    <p>新建一个通用的应用common</p> 
    <pre data-index="86" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">python manage.py startapp common
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <p>models.py</p> 
    <pre data-index="87" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from django.conf <span class="token function">import</span> settings
    from django.db <span class="token function">import</span> models
    
    <span class="token comment"># Create your models here.</span>
    <span class="token comment"># 用户信息</span>
    <span class="token comment"># @python_2_unicode_compatible</span>
    class UserProfile<span class="token punctuation">(</span>models.Model<span class="token punctuation">)</span>:
        <span class="token string">""</span>"
        用户档案
        <span class="token string">""</span>"
        user <span class="token operator">=</span> models.OneToOneField<span class="token punctuation">(</span>settings.AUTH_USER_MODEL, <span class="token assign-left variable">on_delete</span><span class="token operator">=</span>models.CASCADE, <span class="token assign-left variable">related_name</span><span class="token operator">=</span><span class="token string">'userprofile'</span>, <span class="token punctuation">)</span>
        mobile_phone <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>blank<span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True, <span class="token assign-left variable">max_length</span><span class="token operator">=</span><span class="token number">200</span>, <span class="token assign-left variable">verbose_name</span><span class="token operator">=</span><span class="token string">'电话号码'</span><span class="token punctuation">)</span>
        nickname <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>blank<span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True, <span class="token assign-left variable">max_length</span><span class="token operator">=</span><span class="token number">200</span><span class="token punctuation">)</span>
        address <span class="token operator">=</span> models.CharField<span class="token punctuation">(</span>blank<span class="token operator">=</span>True, <span class="token assign-left variable">null</span><span class="token operator">=</span>True, <span class="token assign-left variable">max_length</span><span class="token operator">=</span><span class="token number">400</span><span class="token punctuation">)</span>
        created <span class="token operator">=</span> models.DateTimeField<span class="token punctuation">(</span>auto_now_add<span class="token operator">=</span>True<span class="token punctuation">)</span>
        updated <span class="token operator">=</span> models.DateTimeField<span class="token punctuation">(</span>auto_now<span class="token operator">=</span>True<span class="token punctuation">)</span>
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li></ul></pre> 
    <p>admin.py</p> 
    <pre data-index="88" class="set-code-hide prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;"><span class="token comment"># Register your models here.</span>
    from wagtail.contrib.modeladmin.options <span class="token function">import</span> <span class="token punctuation">(</span>
        ModelAdmin, ModelAdminGroup, modeladmin_register<span class="token punctuation">)</span>
    from .models <span class="token function">import</span> <span class="token punctuation">(</span>
        UserProfile, <span class="token punctuation">)</span>
    
    
    class UserProfileAdmin<span class="token punctuation">(</span>ModelAdmin<span class="token punctuation">)</span>:
        model <span class="token operator">=</span> UserProfile
        menu_label <span class="token operator">=</span> <span class="token string">'用户档案'</span>  <span class="token comment"># ditch this to use verbose_name_plural from model</span>
        menu_icon <span class="token operator">=</span> <span class="token string">'placeholder'</span>  <span class="token comment"># change as required</span>
        list_display <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'user'</span>, <span class="token string">'mobile_phone'</span>,<span class="token string">'nickname'</span>,<span class="token string">'address'</span><span class="token punctuation">)</span>
        list_filter <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'user'</span>,<span class="token punctuation">)</span>
        search_fields <span class="token operator">=</span> <span class="token punctuation">(</span><span class="token string">'user'</span>, <span class="token string">'mobile_phone'</span><span class="token punctuation">)</span>
    
    <span class="token comment"># Now you just need to register your customised ModelAdmin class with Wagtail</span>
    <span class="token comment"># modeladmin_register(ImageAdmin)</span>
    
    modeladmin_register<span class="token punctuation">(</span>UserProfileAdmin<span class="token punctuation">)</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><div class="hide-preCode-box"><span class="hide-preCode-bt" data-report-view="{"spm":"1001.2101.3001.7365"}"><img class="look-more-preCode contentImg-no-view" src="https://1000bd.com/contentImg/2022/06/27/191644837.png" alt="" title=""></span></div><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li><li style="color: rgb(153, 153, 153);">11</li><li style="color: rgb(153, 153, 153);">12</li><li style="color: rgb(153, 153, 153);">13</li><li style="color: rgb(153, 153, 153);">14</li><li style="color: rgb(153, 153, 153);">15</li><li style="color: rgb(153, 153, 153);">16</li><li style="color: rgb(153, 153, 153);">17</li><li style="color: rgb(153, 153, 153);">18</li><li style="color: rgb(153, 153, 153);">19</li></ul></pre> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/cec398ffb6f4f2b8.png" alt="在这里插入图片描述"></p> 
    <h2><a name="t74"></a><a id="_2013"></a>通过接口添加用户档案</h2> 
    <h2><a name="t75"></a><a id="token_2018"></a>通过接口认证获得token方法</h2> 
    <h3><a name="t76"></a><a id="_2019"></a>流程</h3> 
    <p>前端通过用户名密码访问token获取接口,获取token,存储在本地,以后再访问需要认证的资源,可以带着这个token访问接口,后端即认为是此用户名密码用户访问。<br> 目前常用的为客户端webstorage,服务端token;cookie和session方法不再常用</p> 
    <h3><a name="t77"></a><a id="_2023"></a>使用方法</h3> 
    <p>要使用 TokenAuthentication 方案 ,需要在setting包含rest_framework.authtoken应用项;并且配置认证类包含TokenAuthentication。</p> 
    <pre data-index="89" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">INSTALLED_APPS <span class="token operator">=</span> <span class="token punctuation">[</span>
        <span class="token punctuation">..</span>.
        <span class="token string">'rest_framework.authtoken'</span>
    <span class="token punctuation">]</span>
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre> 
    <p>增加认证类</p> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/b1cbdbaae9efbcd7.png" alt="在这里插入图片描述"></p> 
    <p>当使用 TokenAuthentication, 你可能需要通过提供用户名和密码而获得token这样一个机制。REST framework提供了一个内置的 view 来实现这个功能。只需要添加 obtain_auth_token view 到你的 URLconf就可以使用它。</p> 
    <pre data-index="90" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">from rest_framework.authtoken import views
    urlpatterns += [
        path('api-token-auth/', views.obtain_auth_token)
    ]
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li></ul></pre> 
    <p>用户前端访问这个接口,只需要这一行代码即完成token的生成并返回。<br> Note that the URL part of the pattern can be whatever you want to use.</p> 
    <p>The obtain_auth_token view will return a JSON response when valid username and password fields are POSTed to the view using form data or JSON:</p> 
    <pre data-index="91" class="set-code-show prettyprint"><code class="has-numbering" onclick="mdcp.signin(event)" style="position: unset;">{ 'token' : '9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b' }
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li></ul></pre> 
    <h3><a name="t78"></a><a id="_2055"></a>配置完成后的数据库迁移</h3> 
    <pre data-index="92" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">manage.py makemigrations 
    manage.py migrate
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li></ul></pre> 
    <p>及<br> rest_framework.authtoken<br> 应用提供了数据库迁移。</p> 
    <pre data-index="93" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">C:<span class="token punctuation">\</span>djproject<span class="token punctuation">\</span>eshop<span class="token operator">></span>python manage.py makemigrations
    Migrations <span class="token keyword">for</span> <span class="token string">'computerapp'</span><span class="token builtin class-name">:</span>
      computerapp<span class="token punctuation">\</span>migrations<span class="token punctuation">\</span>0002_auto_20210404_1048.py
        - Change Meta options on category
        - Change Meta options on product
        - Alter field name on category
        - Alter field category on product
        - Alter field model on product
        - Alter field price on product
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li><li style="color: rgb(153, 153, 153);">7</li><li style="color: rgb(153, 153, 153);">8</li><li style="color: rgb(153, 153, 153);">9</li><li style="color: rgb(153, 153, 153);">10</li></ul></pre> 
    <pre data-index="94" class="set-code-show prettyprint"><code class="prism language-bash has-numbering" onclick="mdcp.signin(event)" style="position: unset;">C:<span class="token punctuation">\</span>djproject<span class="token punctuation">\</span>eshop<span class="token operator">></span>python manage.py migrate
    Operations to perform:
      Apply all migrations: admin, auth, authtoken, computerapp, contenttypes, sessions
    Running migrations:
      Applying computerapp.0002_auto_20210404_1048<span class="token punctuation">..</span>. OK
    
    <div class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"></div></code><ul class="pre-numbering" style=""><li style="color: rgb(153, 153, 153);">1</li><li style="color: rgb(153, 153, 153);">2</li><li style="color: rgb(153, 153, 153);">3</li><li style="color: rgb(153, 153, 153);">4</li><li style="color: rgb(153, 153, 153);">5</li><li style="color: rgb(153, 153, 153);">6</li></ul></pre> 
    <h3><a name="t79"></a><a id="urls_2087"></a>在根urls增加</h3> 
    <p><img src="https://1000bd.com/contentImg/2024/03/25/cad784145d6042c1.png" alt="在这里插入图片描述"></p> 
    <p>第一行为引入views<br> 第二行为增加认证功能<br> 第三行为获得token功能,利用了rest自带功能</p>
                    </div>
                        </div>
                    </li>
    
                    <li class="list-group-item ul-li">
    
                        <b>相关阅读:</b><br>
                        <nobr>
    <a href="/Article/Index/1159501">【一包通刷】晶晨S905L3A/B_完美AI语音线刷包_打开ADB_ROOT权限</a>                            <br />
    <a href="/Article/Index/1286156">华纳云:如何进行HTTP服务器状态代码解析</a>                            <br />
    <a href="/Article/Index/1424312">golang工程——opentelemetry简介、架构、概念、追踪原理</a>                            <br />
    <a href="/Article/Index/1192193">java毕业设计班导师日常事务管理系统mybatis+源码+调试部署+系统+数据库+lw</a>                            <br />
    <a href="/Article/Index/1478362">污水处理智能化:污水处理拓扑图的未来发展趋势</a>                            <br />
    <a href="/Article/Index/1199247">数据库范式大白话解释</a>                            <br />
    <a href="/Article/Index/1418523">如何设计元宇宙展厅,元宇宙展厅的展示和交互形式有哪些?</a>                            <br />
    <a href="/Article/Index/1371520">Linux gcc和make学习</a>                            <br />
    <a href="/Article/Index/1184951">(附源码)springboot物流配货管理系统 毕业设计 250858</a>                            <br />
    <a href="/Article/Index/1592589">未来IT新潮:共探技术革命与行业趋势</a>                            <br />
                        </nobr>
                    </li>
                    <li class="list-group-item from-a mb-2">
                        原文地址:https://blog.csdn.net/gsl371/article/details/115868718
                    </li>
    
                </ul>
            </div>
    
            <div class="col-lg-4 col-sm-12">
                <ul class="list-group" style="word-break:break-all;">
                    <li class="list-group-item ul-li-bg" aria-current="true">
                        最新文章
                    </li>
                    <li class="list-group-item ul-li">
                        <nobr>
    <a href="/Article/Index/1484446">攻防演习之三天拿下官网站群</a>                            <br />
    <a href="/Article/Index/1515268">数据安全治理学习——前期安全规划和安全管理体系建设</a>                            <br />
    <a href="/Article/Index/1759065">企业安全 | 企业内一次钓鱼演练准备过程</a>                            <br />
    <a href="/Article/Index/1485036">内网渗透测试 | Kerberos协议及其部分攻击手法</a>                            <br />
    <a href="/Article/Index/1877332">0day的产生 | 不懂代码的"代码审计"</a>                            <br />
    <a href="/Article/Index/1887576">安装scrcpy-client模块av模块异常,环境问题解决方案</a>                            <br />
    <a href="/Article/Index/1887578">leetcode hot100【LeetCode 279. 完全平方数】java实现</a>                            <br />
    <a href="/Article/Index/1887512">OpenWrt下安装Mosquitto</a>                            <br />
    <a href="/Article/Index/1887520">AnatoMask论文汇总</a>                            <br />
    <a href="/Article/Index/1887496">【AI日记】24.11.01 LangChain、openai api和github copilot</a>                            <br />
                        </nobr>
                    </li>
                </ul>
    
                <ul class="list-group pt-2" style="word-break:break-all;">
                    <li class="list-group-item ul-li-bg" aria-current="true">
                        热门文章
                    </li>
                    <li class="list-group-item ul-li">
                        <nobr>
    <a href="/Article/Index/888177">十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!</a>                            <br />
    <a href="/Article/Index/797680">奉劝各位学弟学妹们,该打造你的技术影响力了!</a>                            <br />
    <a href="/Article/Index/888183">五年了,我在 CSDN 的两个一百万。</a>                            <br />
    <a href="/Article/Index/888179">Java俄罗斯方块,老程序员花了一个周末,连接中学年代!</a>                            <br />
    <a href="/Article/Index/797730">面试官都震惊,你这网络基础可以啊!</a>                            <br />
    <a href="/Article/Index/797725">你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法</a>                            <br />
    <a href="/Article/Index/797702">心情不好的时候,用 Python 画棵樱花树送给自己吧</a>                            <br />
    <a href="/Article/Index/797709">通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!</a>                            <br />
    <a href="/Article/Index/797716">13 万字 C 语言从入门到精通保姆级教程2021 年版</a>                            <br />
    <a href="/Article/Index/888192">10行代码集2000张美女图,Python爬虫120例,再上征途</a>                            <br />
                        </nobr>
                    </li>
                </ul>
    
            </div>
        </div>
    </div>
    <!-- 主体 -->
    
    
        <!--body结束-->
        <!--这里是footer模板-->
        
        <!--footer-->
    <nav class="navbar navbar-inverse navbar-fixed-bottom">
        <div class="container">
            <div class="row">
                <div class="col-md-12">
                    <div class="text-muted center foot-height">
                        Copyright © 2022 侵权请联系<a href="mailto:2656653265@qq.com">2656653265@qq.com</a>   
                        <a href="https://beian.miit.gov.cn/" target="_blank">京ICP备2022015340号-1</a>
                    </div>
                    <div style="width:300px;margin:0 auto; padding:0px 5px;">
                        <a href="/regex.html">正则表达式工具</a>
                        <a href="/cron.html">cron表达式工具</a>
                        <a href="/pwdcreator.html">密码生成工具</a>
                    </div>
                    <div style="width:300px;margin:0 auto; padding:5px 0;">
                        <a target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010502049817" style="display:inline-block;text-decoration:none;height:20px;line-height:20px;">
                        <img src="" style="float:left;" /><p style="float:left;height:20px;line-height:20px;margin: 0px 0px 0px 5px; color:#939393;">京公网安备 11010502049817号</p></a>
                    </div>
                </div>
            </div>
        </div>
      
    </nav>
    <!--footer-->
    
        <!--footer模板结束-->
    
        <script src="/js/plugins/jquery/jquery.js"></script>
        <script src="/js/bootstrap.min.js"></script>
    
        <!--这里是scripts模板-->
        
    
        
     
    
    
        <!--scripts模板结束-->
    
    </body>
    </html>