Показаны сообщения с ярлыком kikola. Показать все сообщения
Показаны сообщения с ярлыком kikola. Показать все сообщения

25 ноября 2010 г.

Форматируем datetime.timedelta в что-то человеко-читаемое

Оговорюсь сразу, тем кому за глаза хватает print(datetime.timedelta(seconds=99660)) для форматирования и понимания содержимого datetime.timedelta могут смело не читать дальше.

Мне же приходится работать с datetime.timedelta очень часто и потому меня совершенно не устраивали встроенные возможности форматирования дельт. Чего мне не хватало больше всего так это вывода дельты в формате "G:i", говоря языком встроенного шаблонного фильтра date, т.е. показать общее кол-во часов и кол-во минут (не всех, а только остатка) для дельты. Именно для удовлетворения этих нужд я начал писать связку функций str_to_timedelta / timedelta_to_str, которые пару часов назад приняли окончательный вид.

Как они работают? Очень просто,

>>> import datetime
>>> from kikola.utils import str_to_timedelta, timedelta_to_str
>>> delta = datetime.timedelta(seconds=99660)
>>> timedelta_to_str(delta)
... u'27:41'
>>> timedelta_to_str(delta, 'd l, h:i:s')
... u'1 day, 03:41:00'
>>> timedelta_to_str(delta, 'f')
... u'1d 3:41'
>>> timedelta_to_str(delta, 'F')
... u'1 day, 3:41'
>>> timedelta_to_str(delta, 'S')
... u'99660'
>>> str_to_timedelta('27:41') == delta
... True
>>> timedelta_to_str('1 day, 03:41:00', 'd l, h:i:s') == delta
... True
>>> str_to_timedelta('1d 3:41') == delta
... True
>>> str_to_timedelta('1 day, 3:41') == delta
... True
>>> str_to_timedelta('99660', 'S') == delta
... True

Как видите, все действительно просто. Плюс к тому, если вам нужно использовать эти функции в шаблонах, вы можете воспользоваться фильтром timedelta из шаблонной библиотеки timedelta_tags.

{% load timedelta_tags %}
{{ delta|timedelta:"G:i:s" }}

Весь этот код довольно успешно живет в моем проекте kikola, полностью покрыт тестами и работает с Django 1.0+. Чтобы окончательно не углубляться, скажу только, что вы можете посмотреть все доступные форматы для форматирования в комментариях к timedelta_to_str, а также при частом использовании формата, отличного от дефолтного "G:i" вы можете указать его в TIMEDELTA_FORMAT переменной в настройках проекта, и затем str_to_timedelta и timedelta_to_str будут использовать указанный формат, как формат по умолчанию.

18 апреля 2009 г.

Давайте просто поищем!

Как Вы, наверное, знаете поиск и Django - понятия весьма и весьма родные. Каких только приложений не написали для этих целей: и djapian, и и solango, и даже haystack. И это все хорошо, и замечательно, но что делать если нужен простой, совсем простой, поиск по сайту без использования дополнительных поисковых движков? Ответ прост: писать свой очередной велосипед. Что я с удовольствием и сделал!

Итак, знакомтесь: kikola.contrib.basicsearch - приложение для легковесного поиска по любым моделям в вашем проекте.

Для того, чтобы быстро и ясно понять, что оно умеет и как оно работает, предлогаю следующую задачу: в проекте используются стандартная джанговская модель FlatPage и самописная SampleModel. Надо организовать поиск по им, причем так, чтобы результаты из SampleModel печатались раньше, чем результаты из FlatPage.

Решение:

  1. Добавляем kikola.contrib.basicsearch в INSTALLED_APPS;
  2. Настраиваем SEARCH_MODELS там же, в settings'ах:
    SEARCH_MODELS = {
       'flatpages.FlatPage': {
           'description': '{{ obj.content|truncatewords_html:20 }}',
           'fields': ('title', 'content'),
           'priority': 0,
           'title': '{{ obj.title }}',
       },
       'sample.SampleModel': {
           'description': '{{ obj.overview|truncatewords_html:20 }}',
           'fields': ('name', 'slug', 'overview'),
           'priority': 100,
           'trigger': lambda obj: obj.is_active,
       },
    }
    
  3. Добавляем kikola.contrib.basicsearch.urls в ROOT_URLCONF-модуль;
  4. ???
  5. Profit!

Иными словами, сейчас запустив тестовый сервер проекта и зайдя на 127.0.0.1:8000/search/ перед нами будет страничка с поисковой формой в которой мы сможем поискать и по всем FlatPage, и по только активным SampleModel.

зы. Код SampleModel:

from django.db import models
from django.db.models import permalink
from django.utils.translation import ugettext_lazy as _


class SampleModel(models.Model):

   name = models.CharField(_('name'), max_length=64)
   slug = models.CharField(_('slug'), max_length=64)
   overview = models.TextField(_('overview'), blank=True)
   is_active = models.BooleanField(_('actived'), blank=True, default=True)

   def __unicode__(self):
       return self.name

   def get_absolute_url(self):
       return ('sample_urlname', [self.slug])
   get_absolute_url = permalink(get_absolute_url)