【问题标题】:Django templates stripping spaces?Django模板剥离空格?
【发布时间】:2010-10-17 18:54:46
【问题描述】:

我在使用 Django 模板和 CharField 模型时遇到问题。

所以我有一个带有 CharField 的模型,它创建了一个用下划线替换空格的 slug。如果我创建一个对象 Somename Somesurname,这将创建 slug Somename_Somesurname 并按预期显示在模板上。

但是,如果我创建一个对象 Somename Somesurname(注意第二个空格),则会创建 slug Somename__Somesurname,尽管在​​ Django 控制台上我将其视为 @ 987654321@,在模板上显示为 Somename Somesurname

那么 Django 模板会以某种方式去除空格吗?是否有一个过滤器可以用来获取带有空格的名称?

【问题讨论】:

    标签: python django django-templates


    【解决方案1】:

    让我先说@DNS关于为什么没有显示空格的答案是正确的。

    考虑到这一点,此模板过滤器会将字符串中的所有空格替换为 

    用法:

    {{ "hey there  world"|spacify }}
    

    输出将是hey there  world

    代码如下:

    from django.template import Library
    from django.template.defaultfilters import stringfilter
    from django.utils.html import conditional_escape
    from django.utils.safestring import mark_safe
    import re
    
    register = Library()
    
    @stringfilter
    def spacify(value, autoescape=None):
        if autoescape:
        esc = conditional_escape
        else:
        esc = lambda x: x
        return mark_safe(re.sub('\s', '&'+'nbsp;', esc(value)))
    spacify.needs_autoescape = True
    register.filter(spacify)
    

    有关模板过滤器如何工作以及如何安装它们的说明,check out the docs

    【讨论】:

      【解决方案2】:

      Django 在内部将对象视为具有两个空格(根据 repr 输出中的两个下划线和两个空格来判断)。它在模板中只显示一个空格这一事实正是 HTML 的工作原理。请注意,在您刚刚提出的问题中,您输入两个空格的大多数地方,只显示了一个?

      来自HTML4 Spec

      特别是,用户代理应该在生成输出字间距时折叠输入空白序列。

      正如 S.Lott 建议的那样,您可以通过添加调试日志或使用 Firefox 的 Firebug 插件或类似的东西来验证我的猜测是否正确,以查看发送到浏览器的确切内容。然后你就会确定问题出在哪一端。

      如果多个空格对您来说真的很重要,您将需要使用   实体,尽管我不知道您将如何让 Django 使用它们对特定对象的输出进行编码。

      【讨论】:

      • +1:您在浏览器中看到的并不是真实存在的。可能想要添加一些关于使用日志记录来查看实际情况的提示。
      【解决方案3】:

      有一个内置的模板标签spaceless

      {% spaceless %}
          <p>
              <a href="foo/">Foo</a>
          </p>
      {% endspaceless %}
      

      哪些结果:

      <p><a href="foo/">Foo</a></p>
      

      在 django documentation 中阅读更多内容。

      【讨论】:

      • 哇,这对于 display:inline-block 来说太棒了,而不是在元素之间使用手动 html cmets,然后由 IDE “清理”。
      • 标签属性呢?我有很长的循环,模板中有可能的条件,它给了我大量的空格
      【解决方案4】:

      对于 django 模板有问题的人,试试这个: 我的&lt;optgorup&gt; 标签也有类似的问题,我从 django 模型中获取我的值以显示在选择下。我简单地使用了''围绕标签选项来获取带有空格的完整文本。&lt;optgroup label='{{key}}'&gt;

      【讨论】:

        【解决方案5】:

        如果您正在寻找一种方法来删除 html 中的空格,那么这可能就是您正在寻找的:

        html_tag|cut:" "
        

        cut 是一个用于过滤 html 的内置标签。 假设您想为每个 html 标签使用一个 id 以用作永久链接以在您动态生成它时引用,那么例如您的解决方案将是:

        <div id="{{category_name|cut:' ' }}">
        

        django documentation

        【讨论】:

          【解决方案6】:

          Slugify 删除所有前导空格,您需要将其重写为自定义模板标签以获得您所追求的行为。 原来的过滤器代码是这样的

          def slugify(value):
             """
             Normalizes string, converts to lowercase, removes non-alpha characters,
             and converts spaces to hyphens.
             """
             import unicodedata
             value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
             value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
             return mark_safe(re.sub('[-\s]+', '-', value))
          

          将“some string”更改为“some-string”,消除多余的空格。 你可以这样改变它:

          def new_slugify(value):
             """
             Normalizes string, converts to lowercase, removes non-alpha characters,
             and converts spaces to hyphens, does not remove leading whitespace.
             """
             import unicodedata
             value = unicodedata.normalize('NFKD', value).encode('ascii', 'ignore')
             value = unicode(re.sub('[^\w\s-]', '', value).strip().lower())
             return mark_safe(re.sub('[-\s]', '-', value))
          

          这将导致以下行为: “Some  String here”到“some--string-here”

          您可能仍然会遇到前面提到的 html 如何处理多余空格的问题,您必须编写另一个 deslugify 过滤器。

          【讨论】:

            【解决方案7】:

            此标签保留空格和换行符。我复制了Django自己的标签linebreaksbr,然后添加了一行用nbsp替换空格。它不会替换单个空格,因此文本源仍然可读。我写这个是因为我无法让 spacify 标记(其他答案)与 linebreaksbr 一起使用。

            from django.template.defaultfilters import stringfilter
            from django.utils.safestring import mark_safe, SafeData
            from django.utils.text import normalize_newlines
            from django.utils.html import escape
            
            @register.filter(is_safe=True, needs_autoescape=True)
            @stringfilter
            def keep_spacing(value, autoescape=None):
                autoescape = autoescape and not isinstance(value, SafeData)
                value = normalize_newlines(value)
                if autoescape:
                    value = escape(value)
                value = mark_safe(value.replace('  ', ' &nbsp;'))             
                return mark_safe(value.replace('\n', '<br />'))
            

            【讨论】:

              【解决方案8】:

              '\s' 在上述用例中可能没问题,但要小心,这也会替换其他空格,如 '\t''\n'!如果这不是您想要的,请改用" "

              【讨论】:

                猜你喜欢
                • 2017-03-03
                • 2016-12-24
                • 2011-08-21
                • 1970-01-01
                • 2016-10-16
                • 1970-01-01
                • 1970-01-01
                • 2015-07-12
                • 2018-02-26
                相关资源
                最近更新 更多