-
Здравствуйте. Столкнулся с проблемой что при изменении записи в админке не происходит ни обновление кэша ни его сброс. Подскажите пожалуйста, как сделать чтобы для каждого уровня представления сбрасывался кеш при изменении хотя бы одной записи в модельке.
Дано:
пример функции в views.py
@cache_page(60*7)
def newsrender(request):
p = Paginator(News.objects.all(), 20)
cur_page=p.page(request.GET.get('page', 1))
return render_to_response('news.html',{'press_list':cur_page.object_list,'page_obj':cur_page,'firstpage':p.page_range[0]},RequestContext(request))
кусочек из urls.py
(r'^news/$',newsrender),)
Если не трудно можете хотя бы часть кода написать, честно говоря очень трудно для меня понять как -
Желательно без cache.clear() и апликаций не поддерживающих файловых кэш
-
Я бы посмотрел в коде cache_page, как он формирует ключ кэша, а потом подцепился бы на сигнал post_save нужных моделей и удалил бы там нужные данные из кэша.
-
Посмотрите внимательно: с помощью
cache_pageбудет закэширована только первая страница (да и то не всегда).cache_pageне кеширует страницы с GET-параметрами.Чтобы сбросить кеш, нужно узнать ключ и удалить его (есть и другие схемы инвалидации, но не о них речь). Узнать ключ - см.
django.utils.cache.get_cache_key, удалить ключ -cache.delete. Но это немножко хак. Пример можно глянуть тут. cache.delete логично вызвать в методе save у модели News, или повесить на соответствующие сигналы.Модели принято называть в единственном числе, лучше переименовать News в Article или Topic.
Небольшой совет - вместо
render_to_response('news.html', {...}, RequestContext(request))проще писать
direct_to_template('news.html', {...})Еще стоит учесть такую штуку: если используется django 1.2, и на странице есть форма (ну, например, форма логина), в которой есть
csrf_token, и защита включена, CsrfViewMiddleware будет добавлять заголовок Vary: Cookie к ответу. Если при этом еще на сайте стоит что-нибудь вроде Google Analytics или Яндекс.Метрики, то кеширование работать не будет (точнее, все будет постоянно кешироваться, но из кеша данные браться не будут), т.к. аналитики постоянно обновляют куки. Да и если не стоит, то это тоже не поможет, т.к. для разных пользователей-то csrf-токены разные, соответственно для каждого посетителя будет своя версия страницы в кеше.
Если кеширование не требуется, то и прикручивать его не стоит просто так, для галочки.
Ну и кеширование страниц целиком - очень частный случай, со множеством ограничений. Кеширование результатов работы методов менеджеров моделей - imho гораздо более широко применимый подход.
-
Arcady Chumachenko
нашел уже пример http://stackoverflow.com/questions/1995126/invalidating-a-path-from-the-django-cache-recursively но в нем проблема в том что формирует по get_absolute_url которого во многих моделях нет, а также он только для этой модели сбрасывает кеш а не для всей страницы. к примеру :
есть такая функция:
@cache_page(60*15)
def secondrender(request,maint,maint2):
new=get_object_or_404(Second,link2=maint2)
sol={'headtext':new}
if Topik.objects.filter(categor=new.categor).count>0:
sol.update({'topiks':Topik.objects.filter(categor=new.categor)})
if Files.objects.filter(categor=new.categor).count>0:
sol.update({'files':Files.objects.filter(categor=new.categor)})
return render_to_response(new.html,sol,RequestContext(request))
у этой функции только модель Second - имеет get_absolute_url а другие не имеют. Нужно чтобы к примеру при изменении записи в модели Topik обновилась в нужной странице, как это сделать я затрудняюсь.
>>Я бы посмотрел в коде cache_page, как он формирует ключ кэша, а потом подцепился бы на сигнал post_save
по коду видно что возвращает CacheMiddleware, который в свою очередь формирует по request.path. В сигналах надо самостоятельно передавать путь для request.path
Вопрос в том что делать с моделями у которых нету get_absolute_url -
Михаил Коробов
Если организовать кеширование фрагментов шаблона то как можно сбросить кеш при изменении записи, то есть какая должна быть функция которая передастся post_save ? -
точно такая же: нужно как-то вычислить ключ и вызвать cache.delete
http://www.google.ru/search?&q=django+template+cache+invalidation
-
Михаил Коробов
я вот и пишу потому что не знаю как вычислить ключ. у других людей спрашивал они с помощью cache.set задавали id ключа а потом его удаляли. Как правильно задать id ключа я не знаю. Хотя бы часть кода бы получить чтобы уже самому допилить -
сложно найти нужную строчку среди 40 строк middleware?
-
>сложно найти нужную строчку среди 40 строк middleware?
эта строка по request.path создает ключ кэша, что делать с теми моделями у которых нету get_absolute_url ? -
Причем здесь вообще get_absolute_url? У Вас в кэше есть вьюха, которая выводит один конкретный Second и по нескольку Topik и Files. Соответственно, при сохранении Second можно вычислить URL нужной страницы и удалить ее кэш, а при сохранении топиков и файлов чистить кэш для всех Second (хоть это и неправильно - по-хорошему должно быть одна модель == один элемент в кэше).
-
>>Соответственно, при сохранении Second можно вычислить URL нужной страницы и удалить ее кэш, а при сохранении топиков и файлов чистить кэш для всех Second
Каким способом вычисляется url Second, через get_absolute_url ? Я так понял для топиков и файлов нужно сделать выборку к какому они пристыкованы Second и удалить ключ Second по url ? -
Каким способом вычисляется url Second, через get_absolute_url ?
Вы у меня спрашиваете, как в Вашей программе собираются url-ы? :)
Я так понял для топиков и файлов нужно сделать выборку к какому они пристыкованы Second и удалить ключ Second по url ?
При Вашей постановке задачи - да. Но, как правильно заметил Михаил, не надо без особой нужды кэшировать страницы целиком, в большинстве случаев на практике такой кэш окажется чуть ли не медленнее, чем вообще никакого из-за постоянной перезаписи.
Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.

