Шаблоны Django зачистки пробелов? - PullRequest
13 голосов
/ 06 апреля 2009

У меня проблемы с шаблонами Django и моделями CharField.

Итак, у меня есть модель с CharField, которая создает слаг, заменяющий пробелы подчеркиванием. Если я создаю объект, Somename Somesurname, это создает слаг Somename_Somesurname и отображается в соответствии с ожиданиями в шаблоне.

Однако, если я создаю объект, Somename Somesurname (обратите внимание на второй пробел), слаг Somename__Somesurname создается, и хотя на консоли Django я вижу это как <Object: Somename Somesurname> , на шаблоне это отображается как Somename Somesurname .

Так шаблоны Django как-то убирают пробелы? Можно ли использовать фильтр для получения имени с пробелами?

Ответы [ 6 ]

34 голосов
/ 06 апреля 2009

Позвольте мне предисловие, сказав, что @ 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)

Чтобы узнать, как работают фильтры шаблонов и как их устанавливать, посмотрите документы .

10 голосов
/ 06 апреля 2009

Django видит объект как имеющий два пробела (судя по двум подчеркиваниям и двум пробелам в выводе repr). Тот факт, что он отображается только с одним пробелом в шаблоне - это то, как работает HTML. Обратите внимание, как в только что заданном вопросе в большинстве мест, где вы указали два пробела, отображается только одно?

Из HTML4 Spec :

В частности, пользовательские агенты должны свернуть входные последовательности пробелов при создании выходного межсловного пространства.

Как предположил С.Лотт, вы можете проверить правильность моего предположения, добавив отладочные логи, или воспользовавшись плагином Firebug для Firefox или чем-то подобным, чтобы точно узнать, что отправляется в браузер. Тогда вы точно будете знать, в чём заключается проблема.

Если для вас действительно важны несколько пробелов, вам нужно будет использовать сущность &nbsp;, хотя я не знаю, как вы можете заставить Django кодировать выходные данные этого конкретного объекта, используя их.

6 голосов
/ 21 апреля 2012

есть встроенный шаблон тега без пробелов

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

Какие результаты:

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

Подробнее в документации Django .

0 голосов
/ 09 сентября 2013

'\s' может быть в порядке в случае использования, описанном выше, но будьте осторожны, это заменяет другие пробелы, такие как '\t' или '\n'! Если это не то, что вам нужно, просто используйте " ".

0 голосов
/ 30 ноября 2012

Этот тег содержит пробелы и переводы строк. Я скопировал собственный тег строки Django breaksbr, а затем добавил строку, чтобы заменить пробелы на 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 />'))
0 голосов
/ 06 апреля 2009

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

, который заменяет "некоторую строку" на "некоторую строку", убивая лишние пробелы. Вы можете изменить это так:

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 обрабатывает лишние пробелы, вам придется написать еще один фильтр удаления ошибок.

...