[Django] 11 - Template, JS and CSS

创建一个简单的 Django 项目

Ref: https://www.runoob.com/django/django-first-app.html

Ref: https://www.runoob.com/django/django-template.html

 

一、基本套路

|-- HelloWorld
|   |-- __init__.py
|   |-- asgi.py
|   |-- settings.py
|   |-- urls.py
|   |-- views.py
|   `-- wsgi.py
`-- manage.py

首先 view,但如何被调用? 

from django.http import HttpResponse
 
def hello(request):
    return HttpResponse("Hello world ! ")  # <---- 可以使用 template

url 中,直接import 并调用即可。

from django.conf.urls import url
 
from . import views
 
urlpatterns = [
    url(r'^$', views.hello),
]

 

 

二、使用模板

  • 配置模板路径

...
TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')],       # 修改位置
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]
...

 

  • 带 template 的 view

不同于上面的 hello,这个开始使用 模板。 url调用也是上述的套路。

from django.shortcuts import render
 
defhello_runoob(request):
    context          = {}
    context['hello'] = 'Hello World!'
    return render(request, 'runoob.html', context)  # context 改为: {"hello": 'Hello World!'}

context 作为参数进 template html。

 

 

三、模板中常用的语法规则

  • 列表

.0 是通过 点,而不是[ ]。

<p>{{ views_list }}</p>   # 取出整个列表
<p>{{ views_list.0 }}</p> # 取出列表的第一个元素

 

  • 字典

name 就是 key

<p>{{ views_dict }}</p>
<p>{{ views_dict.name }}</p>

 

  • 过滤器

将列表中的第一个元素大写化。也可以有参数。

{{ my_list|first|upper }}
{{ pub_date|date:"F j, Y" }}  # date : 按指定的格式字符串参数格式化 date 或者 datetime 对象

 

    • 空则默认值

当 name 是空值时,提供一个默认值。

# 这些是默认值: 0  0.0  False  0j  ""  []  ()  set()  {}  None

{{ name|default:"菜鸟教程666" }}

 

    • 返回长度

{{ name|length}}

 

filesizeformat, 以更易读的方式显示文件的大小

date, 根据给定格式对一个日期变量进行格式化。

truncatechars, 如果字符串包含的字符总个数多于指定的字符数量,那么会被截断掉后面的部分。

safe, 将字符串标记为安全,不需要转义。

  

  • if/else 标签

{% if condition1 %}
   ... display 1
{% elif condition2 %}
   ... display 2
{% else %}
   ... display 3
{% endif %}

 

    • ifequal / ifnotequal 标签

看上去 跟if/else没有 大区别。

{% ifequal section 'sitenews' %}
    <h1>Site News</h1>
{% else %}
    <h1>No News Here</h1>
{% endifequal %}

 

  • for 标签

{% for i in views_list %}
{{ i }}
{% endfor %}

 

    • 遍历字典

{% for i,j in views_dict.items %}
{{ i }}---{{ j }}
{% endfor %}

  

    • forloop

在 {% for %} 标签里可以通过 {{forloop}} 变量获取循环序号。

      • forloop.counter: 顺序获取循环序号,从 1 开始计算
      • forloop.counter0: 顺序获取循环序号,从 0 开始计算
      • forloop.revcounter: 倒叙获取循环序号,结尾序号为 1
      • forloop.revcounter0: 倒叙获取循环序号,结尾序号为 0
      • forloop.first(一般配合if标签使用): 第一条数据返回 True,其他数据返回 False
      • forloop.last(一般配合if标签使用): 最后一条数据返回 True,其他数据返回 False

 

注意,这里只是显示index,i的内容可自行填补的每行的后边。

{% for i in listvar %}
    {{ forloop.counter }}
    {{ forloop.counter0 }}
    {{ forloop.revcounter }}
    {{ forloop.revcounter0 }}
    {{ forloop.first }}
    {{ forloop.last }}
{% endfor %}

 

    • {% empty %}

如果列表是空,则显示默认的内容。可以理解为 list 的默认值。

{% for i in listvar %}
    {{ forloop.counter0 }}
{% empty %}
    空空如也~
{% endfor %}

 

    • 嵌套 {% for %} 标签

{% for athlete in athlete_list %}
    <h1>{{ athlete.name }}</h1>
    <ul>
    {% for sport in athlete.sports_played %}
        <li>{{ sport }}</li>
    {% endfor %}
    </ul>
{% endfor %}

 

  • 注释标签

{# 这是一个注释 #}

 

  • include 标签

允许在模板中包含其它的模板的内容。,例如,包含了 nav.html 模板

{% include "nav.html" %}

 

 

四、模板继承

  • 父模板 与 子模板

{% block 名称 %} 
预留给子模板的区域,可以设置设置默认内容
{% endblock 名称 %}

 

先准备一个父模板:HelloWorld/templates/base.html 

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body>
    <h1>Hello World!</h1>
    <p>菜鸟教程 Django 测试。</p>
{% block mainbody %} <p>original</p> {% endblock %} </body> </html>

 

子模板:HelloWorld/templates/runoob.html

{% extends "base.html" %}
 
{% block mainbody %}
<p>继承了 base.html 文件</p>
{% endblock %}

 

 

 

本地 css/js

一、普通套路

Ref: 小猿圈python之Django怎么使用本地css/js文件

Ref: 正则解析iframe,非常好

 

Ref: https://regex101.com/

(\S+)=["']?((?:.(?!["']?\s+(?:\S+)=|[>"']))+.)["']?

 

 

二、ADMIN UI


INSTALLED_APPS = INSTALLED_APPS + [ 'debug_toolbar', 'django_extensions', 'wagtail.contrib.styleguide', ]

Ref: https://github.com/CodingForEverybody/learn-wagtail/commit/bd533b96e6f6297e5c5ebf011f6d544f56f6ab88

暫時不實用,以後有用到再研究。

 

 

 

Template Fragment Caching

Ref: Wagtail CMS: How to Add Template Fragment Caching

一、缓存配置

首先确保,打开这部分内容。

Ref: Django 缓存框架,可见下面是使用了缓存中的一种。

# Uncomment this line to enable template caching
# Dont forget to change the LOCATION path
# CACHES = {
#     "default": {
#         "BACKEND": "django.core.cache.backends.filebased.FileBasedCache",
#         "LOCATION": "/path/to/your/site/cache"
#     }
# }

 

 

二、缓存 template 的某个片段

  • 清空 .djcache 文件

手动清空。

from django.core.cache import cache

cache.clear()

 

  • 为片段添加缓存

例如:blog_listing_page.html,以 目录页为例。

{% load wagtailimages_tags wagtailroutablepage_tags cache %}


    <div class="container">
        {% for post in posts %}
            {% cache 604800 blog_post_preview post.id %}
<div class="row mt-5 mb-5">
<div class="col-sm-3"> {% image post.banner_image fill-250x250 as blog_img %} <a href="{{ post.url }}"> <img src="{{ blog_img.url }}" alt="{{ blog_img.alt }}" style='width: 100%;'> </a> </div>
<div class="col-sm-9"> <a href="{{ post.url }}"> <h2>{{ post.custom_title }}</h2> {% if post.specific.subtitle %} <p>{{ post.specific.subtitle }}</p> {% endif %} {# @todo add a summary field to BlogDetailPage; make it a RichTextField with only Bold and Italic enabled. #} <a href="{{ post.url }}" class="btn btn-primary mt-4">Read More</a> </a> </div>
</div>
{% endcache %} {% endfor %} </div>

 

 

三、适时 Remove Caching

Ref: Wagtail CMS: Using the save() method to remove template fragment caching

如果加了缓存,内容修改后,比如博客文章标题修改后,客户端无法及时看到,既然在利用缓存,此时就需要“及时地”放弃缓存内容。

修改,点击save按钮保存,出发一个函数,如下:

from django.core.cache import cache
from django.core.cache.utils import make_template_fragment_key

... ...
def save(self, *args, **kwargs):   """Create a template fragment key.   Then delete the key."""   key = make_template_fragment_key(     "blog_post_preview",     [self.id]   )
  cache.delete(key)   
return super().save(*args, **kwargs)

 

End.

posted @ 2020-12-25 14:43  郝壹贰叁  阅读(123)  评论(0编辑  收藏  举报