Я говорю с точки зрения поддержки. Например есть сайт, написанный другим человеком несколько месяцев назад. Моей целью является писать так, чтобы разабраться было как можно проще. Просмотрев шаблоны, благодаря наследованию и тегам джанги понять что откуда растет очень просто.
Наверное, кешированию не место в шаблонах. но за джанговцами вроде небыло замещено архитектурных просчетов. зачем они тогда его сделали в виде тега? ведь перемешивание MVC они предусмотрительно запретили... надо почитать дискуссии по этой фишке. ее ведь только что добавили в svnку
Согласен. Это просто самое простое решение. В джанге есть сигналы. Можно повесить событие например на сохранение объекта. и в этом событии инвалидировать кэш связанный с сохраненным объектом. вот только если объект встречается во многих местах, то найти и инвалидировать все его кэши не такая тривиальная задача.
Нда, замороченый пример получился.
Ключевая строка - {{ block.super }}. Т.к. список статей и список статей имеющих определенный тег по шаблонам не отличаются я понаследовался от списка статей. Шаблон списка статей (из предыдущей статьи, этому будет равен {{ block.super }}):
{% for article in article_list %}
«a href="{% url article_view article.id %}"»
{{ article.title }}
«/a»
{% endfor %}
Тут тега нет т.к. список статей это основные данные отображения. Но по ленивой природе запросов в бд в django запрос в базу не идет.
Если упростить, то отображения для них будут такими:
@render_to('blog/index.htm')
def index(request):
article_list=Article.objects.filter(public=True)
return {
'article_list': article_list,
}
может быть. но, по-моему, в кэш лучше положить отрендереный кусок нежели дамп объекта который будет каждый раз подыматься, по нему будешь бежать и вставлять куски маркапа... зачем? по мне код и так получается чистый и красивый - не надо бегать по всем пакам templatetags и смотреть не закэшировано ли где чего.
как описать в настройках что хочешь закэшировать кусок шаблона?
лично у меня никаких идей. ориентироваться на имя блока? а если с параметрами? а если надо хранить несколько версий основываясь на контексте вызова?
на счет таймаута согласен. вот хак - перекрыл стандартный тег cache чтоб он понимал, что если ему не дали таймаута первым параметром его надо взять из settings.py
кстати, чтобы не "лазить по всем шаблонам где используется данный фрагмент" нужно использовать наследование и определять блок один раз.
а на счет "засорения всякими cache_" - не согласен. по-моему там им самое место - сразу видишь что и где кэшируется. да и как описать в настройках что хочешь закэшировать кусок шаблона?
Еще подумал: хорошо бы для кэширования запросов избавиться от явного использования API кэша.
Вот за пять минут накидал: chachedQuery.py
Хранит в кеше результаты запроса. Ключем является построенный sql запрос, вытаскиваемый из ихнего sql-построителя.
Пример там же.
UPD: articles_cached[0].get_absolute_url()
тоже работает. так что он подымает полноценный объект.
кодит объекты перед укладкой в кэш он при помощи cPickle/pickle
Про кэширование view-ов я вроде написал вкратце.
Для кэширования sql запросов можно воспользоваться "кэшированием данных":
from blog.models import Article
from django.core.cache import cache
articles=list(Article.objects.all())
cache.set('articles',articles)
articles_cached=cache.get('articles')
print articles_cached
проверил только что - вроде все работает.
На счет обновления кэша по сигналам - действительно я об этом не упомянул. Мне пока хватило инвалидации по таймауту и очистки кэша скриптом генерации public-версии (при изменениях в коде: рестарт апаче, сжатие js и css, пр.).
Но в перспективе - действительно надо :)
А если у меня нет регистрации и пользователе-зависимой информации? Но, к примеру, блоки рандомно меняются. Мне все-таки кажется что кешировать все подряд не стоит - лучше кешировать то, что действительно нужно.
Наверное, кешированию не место в шаблонах. но за джанговцами вроде небыло замещено архитектурных просчетов. зачем они тогда его сделали в виде тега? ведь перемешивание MVC они предусмотрительно запретили... надо почитать дискуссии по этой фишке. ее ведь только что добавили в svnку
Ключевая строка - {{ block.super }}. Т.к. список статей и список статей имеющих определенный тег по шаблонам не отличаются я понаследовался от списка статей. Шаблон списка статей (из предыдущей статьи, этому будет равен {{ block.super }}):
{% for article in article_list %}
«a href="{% url article_view article.id %}"»
{{ article.title }}
«/a»
{% endfor %}
Тут тега нет т.к. список статей это основные данные отображения. Но по ленивой природе запросов в бд в django запрос в базу не идет.
Если упростить, то отображения для них будут такими:
@render_to('blog/index.htm')
def index(request):
article_list=Article.objects.filter(public=True)
return {
'article_list': article_list,
}
@render_to('blog/tag_index.htm')
def tag(request, tag_slug):
tag=get_object_or_404(Tag, slug=tag_slug)
article_list=Article.objects.filter(tags=tag, public=True)
return {
'tag': tag,
'article_list': article_list,
}
лично у меня никаких идей. ориентироваться на имя блока? а если с параметрами? а если надо хранить несколько версий основываясь на контексте вызова?
кстати, чтобы не "лазить по всем шаблонам где используется данный фрагмент" нужно использовать наследование и определять блок один раз.
а на счет "засорения всякими cache_" - не согласен. по-моему там им самое место - сразу видишь что и где кэшируется. да и как описать в настройках что хочешь закэшировать кусок шаблона?
я пока не нашел полностью устраивающего меня универсального решения. как найду - отпишусь.
на счет site_cfg:
а мне синковать (sync) удобнее, когда на всех машинах одно и тоже.
я минут 15 тупил че не работает... ;)
Вот за пять минут накидал: chachedQuery.py
Хранит в кеше результаты запроса. Ключем является построенный sql запрос, вытаскиваемый из ихнего sql-построителя.
Пример там же.
тоже работает. так что он подымает полноценный объект.
кодит объекты перед укладкой в кэш он при помощи cPickle/pickle
Для кэширования sql запросов можно воспользоваться "кэшированием данных":
from blog.models import Article
from django.core.cache import cache
articles=list(Article.objects.all())
cache.set('articles',articles)
articles_cached=cache.get('articles')
print articles_cached
проверил только что - вроде все работает.
На счет обновления кэша по сигналам - действительно я об этом не упомянул. Мне пока хватило инвалидации по таймауту и очистки кэша скриптом генерации public-версии (при изменениях в коде: рестарт апаче, сжатие js и css, пр.).
Но в перспективе - действительно надо :)
мне просто интересно когда это может быть надо. разве что если на серваке куча сайтов и один из них совсем не меняется...