Django模板剥离空间?

时间:2009-04-06 11:22:15

标签: python django django-templates

我遇到了Django模板和CharField模型的问题。

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

但是,如果我创建一个对象, Somename Somesurname (注意第二个空格),就会创建slug Somename__Somesurname ,虽然在Django控制台上我将其视为{ {1}},在模板上显示为 Somename Somesurname

Django模板不知何故剥离空间吗?我可以使用过滤器来获取带有空格的名称吗?

8 个答案:

答案 0 :(得分:34)

让我先说一下,@ 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

答案 1 :(得分:10)

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

来自HTML4 Spec

  

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

正如S.Lott建议的那样,您可以通过添加调试日志记录,或使用Firefox的Firebug插件或类似内容来验证我的猜测是否正确,以确切了解发送到浏览器的内容。那么你肯定知道问题出在哪一端。

如果多个空格对您非常重要,则需要使用 实体,但我不知道如何让Django使用它们对该特定对象的输出进行编码。

答案 2 :(得分:6)

内置模板标记无空间

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

结果如何:

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

在django documentation中阅读更多内容。

答案 3 :(得分: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”

如前所述,你仍然可能遇到html如何处理额外空格的问题,你必须编写另一个解散过滤器。

答案 4 :(得分:0)

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

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 />'))

答案 5 :(得分:0)

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

答案 6 :(得分:0)

对于有人对Django模板有疑问的人,请尝试以下操作: 我的./binaryName标签也有类似的问题,我正在从Django模型中获取值以显示在select下。我简单地在标签选项周围使用了package controllers; import play.*; import play.mvc.*; import views.html.*; import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.sql.SQLException; import java.text.DecimalFormat; import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Arrays; import java.util.Date; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Set; import java.lang.NullPointerException; import java.io.FileNotFoundException; public class Application extends Controller { public static Result index() { File storeDirectory = null; try { storeDirectory = new File("public/myFiles"); } catch (NullPointerException nullPointerException) { System.err.println("Meh NullPointerException when creating storeDirectory!"); nullPointerException.printStackTrace(); } if (!storeDirectory.exists()) { storeDirectory.mkdirs(); } System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- storeDirectory.getAbsolutePath(): " + storeDirectory.getAbsolutePath());//check //----------------------------------------------------------START System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Does storeDirectory exist? " + storeDirectory.exists()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is storeDirectory a directory? " + storeDirectory.isDirectory()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is storeDirectory a file? " + storeDirectory.isFile()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is storeDirectory hidden? " + storeDirectory.isHidden()); if (storeDirectory.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT EXECUTE. REMEDYING THAT."); storeDirectory.setExecutable(true); } if (storeDirectory.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT READ. REMEDYING THAT."); storeDirectory.setReadable(true); } if (storeDirectory.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT WRITE. REMEDYING THAT."); storeDirectory.setWritable(true); } System.out.println(" :::::::::::::::::::::::::::::::::: AFTER!!!"); if (storeDirectory.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT EXECUTE. REMEDYING THAT."); storeDirectory.setExecutable(true, false); } if (storeDirectory.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT READ. REMEDYING THAT."); storeDirectory.setReadable(true, false); } if (storeDirectory.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT WRITE. REMEDYING THAT."); storeDirectory.setWritable(true, false); } System.out.println(" :::::::::::::::::::::::::::::::::: AFTER AFTER AFTER!!!"); if (storeDirectory.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT EXECUTE."); } if (storeDirectory.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT READ."); } if (storeDirectory.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT WRITE."); } //----------------------------------------------------------END File actualFile = null; try { actualFile = new File(storeDirectory, "one_1.xls"); } catch (NullPointerException nullPointerException) { System.err.println("Meh NullPointerException when creating actualFile!"); nullPointerException.printStackTrace(); } System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- actualFile.getAbsolutePath(): " + actualFile.getAbsolutePath());//check //----------------------------------------------------------START System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Does actualFile exist? " + actualFile.exists()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is actualFile a directory? " + actualFile.isDirectory()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is actualFile a file? " + actualFile.isFile()); System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- Is actualFile hidden? " + actualFile.isHidden()); if (actualFile.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT EXECUTE. REMEDYING THAT."); actualFile.setExecutable(true); } if (actualFile.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT READ. REMEDYING THAT."); actualFile.setReadable(true); } if (actualFile.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT WRITE. REMEDYING THAT."); actualFile.setWritable(true); } System.out.println(" :::::::::::::::::::::::::::::::::: AFTER!!!"); if (actualFile.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT EXECUTE. REMEDYING THAT."); actualFile.setExecutable(true, false); } if (actualFile.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT READ. REMEDYING THAT."); actualFile.setReadable(true, false); } if (actualFile.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, CAN NOT WRITE. REMEDYING THAT."); actualFile.setWritable(true, false); } System.out.println(" :::::::::::::::::::::::::::::::::: AFTER AFTER AFTER!!!"); if (actualFile.canExecute()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN EXECUTE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT EXECUTE."); } if (actualFile.canRead()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN READ."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT READ."); } if (actualFile.canWrite()) { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- YES, CAN WRITE."); } else { System.out.println(" :-:-:-:-:-:-:-:-:-:-:-:-:- NO, STILL CAN NOT WRITE."); } //----------------------------------------------------------END FileOutputStream fileOutputStream = null; try { fileOutputStream = new FileOutputStream(actualFile); } catch (FileNotFoundException e) { System.out.println("FileNotFoundException occurred while creating outStream!");//check System.out.println("FileNotFoundException occurred while creating outStream! getMessage(): " + e.getMessage());//check System.out.println("FileNotFoundException occurred while creating outStream! getLocalizedMessage(): " + e.getLocalizedMessage());//check e.printStackTrace();//check } System.out.println("\n\n\n\n"); if (fileOutputStream == null) { System.out.println("fileOutputStream IS null"); } else { System.out.println("fileOutputStream IS NOT null"); } return ok(index.render("Your new application is ready.")); } } 来获取带有空格的完整文本。<optgorup>

答案 7 :(得分:0)

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

html_tag|cut:" "

cut是用于过滤html的内置标记。 假设您要为每个html标记使用一个id,以便在动态生成此html标记时进行引用,例如,解决方案将是:

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

django documentation