16

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

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

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

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

4

8 回答 8

36

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

考虑到这一点,此模板过滤器将替换字符串中的任何空格&nbsp;

用法:

{{ "hey there  world"|spacify }}

输出将是hey&nbsp;there&nbsp;&nbsp;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)

有关模板过滤器如何工作以及如何安装它们的说明,请查看文档

于 2009-04-06T16:46:38.150 回答
11

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

HTML4 规范

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

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

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

于 2009-04-06T11:45:05.380 回答
9

有一个内置的模板标签spaceless

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

结果:

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

在 django文档中阅读更多内容。

于 2012-04-21T12:16:28.770 回答
1

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

于 2019-09-03T08:45:11.230 回答
1

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

html_tag|cut:" "

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

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

Django 文档

于 2020-03-19T13:58:20.630 回答
0

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 过滤器。

于 2009-04-06T12:41:11.407 回答
0

此标签保留空格和换行符。我复制了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 />'))
于 2012-11-30T09:21:57.037 回答
0

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

于 2013-09-08T21:04:24.393 回答