【问题标题】:Passing and Using Dictionaries in Django Template Tags在 Django 模板标签中传递和使用字典
【发布时间】:2021-09-08 00:35:32
【问题描述】:

我有一个函数使用 psutil 库来获取 CPU 使用率数据。

import psutil
from django.utils.safestring import mark_safe

def get_cpu():
    """Gets the system-wide CPU utilisation percentage"""
    utilisation = list(psutil.cpu_percent(interval=1, percpu=True))
    cpu_data_utilisation = []
    load_avg_list = []
    cpu_data = {}
    for count in range(len(utilisation)):
        count = count + 1
        cpu_data_utilisation.append({
            "label" : str("CPU " + str(count)),
            "util" : round(utilisation[count-1])
        })
    load_avg_tuple = tuple(psutil.getloadavg())
    load_avg_1 = load_avg_tuple[0]
    load_avg_5 = load_avg_tuple[1]
    load_avg_15 = load_avg_tuple[2]
    load_avg_list.append({
        "1"  : round(load_avg_1),
        "5"  : round(load_avg_5),
        "15" : round(load_avg_15)
    })
    cpu_data = {
        "core_util" : cpu_data_utilisation,
        "load_avg"  : load_avg_list,
    }
    return cpu_data

我还有一个模板标签,它调用并返回get_cpu 函数。

@register.simple_tag
def get_cpu_data():
    return mark_safe(get_cpu())

在 HTML 文件中,添加这两行:

{% get_cpu_data as cpu_data %}
{{ cpu_data }}

渲染:

{'core_util': [{'label': 'CPU 1', 'util': 66}, {'label': 'CPU 2', 'util': 21}, {'label': 'CPU 3', 'util': 62}, {'label': 'CPU 4', 'util': 22}, {'label': 'CPU 5', 'util': 56}, {'label': 'CPU 6', 'util': 22}, {'label': 'CPU 7', 'util': 54}, {'label': 'CPU 8', 'util': 23}], 'load_avg': [{'1': 5, '5': 5, '15': 4}]}

字典有两个键,core_utilload_avg。我想从与键配对的值中取出列表并进行迭代。

下面的模板代码什么也不渲染。

{% for key, val in cpu_data.items %} 
    {{ key }}
{% endfor %}

但是,这个模板代码:

{% for data in cpu_data %} 
    {{ data }}
{% endfor %}

返回这个:

    {
 
    '
 
    c
 
    o
 
    r
 
    e
 
    _
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    [
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    1
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    5
 
    0
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    2
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    1
 
    8
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    3
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    4
 
    3
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    4
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    1
 
    8
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    5
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    3
 
    8
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    6
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    2
 
    0
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    7
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    3
 
    5
 
    }
 
    ,
 
     
 
    {
 
    '
 
    l
 
    a
 
    b
 
    e
 
    l
 
    '
 
    :
 
     
 
    '
 
    C
 
    P
 
    U
 
     
 
    8
 
    '
 
    ,
 
     
 
    '
 
    u
 
    t
 
    i
 
    l
 
    '
 
    :
 
     
 
    1
 
    8
 
    }
 
    ]
 
    ,
 
     
 
    '
 
    l
 
    o
 
    a
 
    d
 
    _
 
    a
 
    v
 
    g
 
    '
 
    :
 
     
 
    [
 
    {
 
    '
 
    1
 
    '
 
    :
 
     
 
    6
 
    ,
 
     
 
    '
 
    5
 
    '
 
    :
 
     
 
    5
 
    ,
 
     
 
    '
 
    1
 
    5
 
    '
 
    :
 
     
 
    4
 
    }
 
    ]
 
    }

一个非常长的无格式字符串,每行一个字符。

我做错了什么,我该如何解决?

【问题讨论】:

    标签: python django list dictionary django-templates


    【解决方案1】:

    在您的模板标签中,您有以下行:

    return mark_safe(get_cpu())
    

    mark_safe 返回一个SafeString,它是str 的子类。这意味着这里发生的事情是您的字典被转换为标记为安全的字符串(实际上是SafeString 的实例)。接下来,当您尝试循环时,它实际上可能并不安全,因此它被模板引擎转义。如果您真的想将其用作字典不要在其上调用mark_safe

    @register.simple_tag
    def get_cpu_data():
        return get_cpu()
    

    您的用例可能是该字典的 contents 是安全的,您可以根据需要将其呈现如下,或者您可以在字典的实际值上使用mark_safe

    {% for key, val in cpu_data.items %} 
        {{ key|safe }}: {{ val|safe }}
    {% endfor %}
    

    【讨论】:

    • mark_safe 是问题所在,感谢您通知我。没有它,我什至可以用钥匙访问字典。
    猜你喜欢
    • 2020-08-21
    • 2019-10-22
    • 2017-05-17
    • 2021-02-15
    • 2017-08-11
    • 2014-03-20
    • 2013-05-06
    • 2021-06-16
    • 2015-03-07
    相关资源
    最近更新 更多