如何在Django模板中嵌入SVG图像

4

我正在尝试在使用 Django 模板构建的网页上显示 SVG 图像。

If I simply put

<figure>
  <embed type="image/svg+xml" src="test.svg" width="75%" height="75%"/>
</figure>

在HTML文件中,SVG文件将被渲染(由Chrome完成)。

But if I try to do the same thing in a django template it does not work. I have also tried using

 <iframe src="bar_chart.svg" width="200" height="200" ></iframe>

还有其他几种变体。

Django中最好的显示SVG图像的方法是什么?


你尝试过使用<img src=....>标签了吗? - undefined
是的,我做了。它没有渲染出来。如果我只在HTML文件中编写并打开,它就可以渲染出来。但是,如果我在Django模板中使用该格式,比如在templates目录下的display.html文件中,它就不会显示。如果我写上<svg>绘制圆形</svg>,它就会画出圆形。基本上,Django无法引用SVG文件。根据我后来查看的内容,似乎我必须使用Flask的with_render方法进行渲染。我刚刚放弃了这个库(用于SVG文件的pygal),开始使用非常简单的chartkick Python Django库。 - undefined
3个回答

9

我强烈建议使用内联SVG。在我的上一份工作中,我尝试将对象嵌入到我们的Django项目中,但是我的同事的弹出窗口拦截程序阻止了它们。

将SVG重命名为HTML扩展名,将SVG放在模板目录之一中,然后使用include标记。

{% include 'bar_chart.svg' %}

内联的最好之处是您可以使用CSS针对SVG中的任何内容进行定位,不好的地方是IE8及更早版本不支持它,Android 2.3及更低版本也是如此。

了解更多关于SVG的信息,请查看https://css-tricks.com/using-svg/


2
这是我为与材料设计图标一起使用而制作的自定义模板标签。我下载了一些SVG图标并将它们放在一个文件夹中。他们使用字体的方式很方便,但需要大量带宽。
示例用法(选择文件名/类名/大小/填充):
{% icon 'face' 'std-icon menu-icon' 32 '#ff0000' %}

import xml.etree.ElementTree as ET

from django import template
from django.utils.safestring import mark_safe

register = template.Library()

ICON_DIR = "/path/to/your/icons/"

@register.simple_tag
def icon(file_name, class_str=None, size=24, fill='#000000'):
    """Inlines a SVG icon from linkcube/src/core/assets/templates/core.assets/icon

    Example usage:
        {% icon 'face' 'std-icon menu-icon' 32 '#ff0000' %}
    Parameter: file_name
        Name of the icon file excluded the .svg extention.
    Parameter: class_str
        Adds these class names, use "foo bar" to add multiple class names.
    Parameter: size
        An integer value that is applied in pixels as the width and height to
        the root element.
        The material.io icons are by default 24px x 24px.
    Parameter: fill
        Sets the fill color of the root element.
    Returns:
        XML to be inlined, i.e.:
        <svg width="..." height="..." fill="...">...</svg>
    """
    path = f'{ICON_DIR}/{file_name}.svg'
    ET.register_namespace('', "http://www.w3.org/2000/svg")
    tree = ET.parse(path)
    root = tree.getroot()
    root.set('class', class_str)
    root.set('width', f'{size}px')
    root.set('height', f'{size}px')
    root.set('fill', fill)
    svg = ET.tostring(root, encoding="unicode", method="html")
    return mark_safe(svg)

2

此答案所述,您可以使用SVG <use> HTML元素和static django模板标签来实现这一点:

{% load static %}
<svg>
  <use 
    href="{% static "bar_chart.svg" %}#id_of_svg_element_to_include"
  >
  </use>
</svg>

但请注意:

  • 您引用的SVG文件中的svg元素必须具有可引用的ID(如上所示的#id_of_svg_element_to_include
  • 您必须确保ID位于svg元素上,而不是例如g元素上,否则use上的widthheight将不适用,详见MDN上宽度和高度属性的注释

不内联的明显好处是SVG可以从您的快速静态文件服务器提供并且可以被缓存。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接