1. Александр

    28.07.2010

    0 ↑
    0 ↓
    Здравствуйте. Столкнулся с проблемой что при изменении записи в админке не происходит ни обновление кэша ни его сброс. Подскажите пожалуйста, как сделать чтобы для каждого уровня представления сбрасывался кеш при изменении хотя бы одной записи в модельке.

    Дано:
    пример функции в 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),)

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

    28.07.2010

    0 ↑
    0 ↓
    Желательно без cache.clear() и апликаций не поддерживающих файловых кэш
  3. Я бы посмотрел в коде cache_page, как он формирует ключ кэша, а потом подцепился бы на сигнал post_save нужных моделей и удалил бы там нужные данные из кэша.

    1. Посмотрите внимательно: с помощью cache_page будет закэширована только первая страница (да и то не всегда). cache_page не кеширует страницы с GET-параметрами.

    2. Чтобы сбросить кеш, нужно узнать ключ и удалить его (есть и другие схемы инвалидации, но не о них речь). Узнать ключ - см. django.utils.cache.get_cache_key, удалить ключ - cache.delete. Но это немножко хак. Пример можно глянуть тут. cache.delete логично вызвать в методе save у модели News, или повесить на соответствующие сигналы.

    3. Модели принято называть в единственном числе, лучше переименовать News в Article или Topic.

    4. Небольшой совет - вместо

      render_to_response('news.html', {...}, RequestContext(request))
      

      проще писать

      direct_to_template('news.html', {...})
      
    5. Еще стоит учесть такую штуку: если используется django 1.2, и на странице есть форма (ну, например, форма логина), в которой есть csrf_token, и защита включена, CsrfViewMiddleware будет добавлять заголовок Vary: Cookie к ответу. Если при этом еще на сайте стоит что-нибудь вроде Google Analytics или Яндекс.Метрики, то кеширование работать не будет (точнее, все будет постоянно кешироваться, но из кеша данные браться не будут), т.к. аналитики постоянно обновляют куки. Да и если не стоит, то это тоже не поможет, т.к. для разных пользователей-то csrf-токены разные, соответственно для каждого посетителя будет своя версия страницы в кеше.

    Если кеширование не требуется, то и прикручивать его не стоит просто так, для галочки.

    Ну и кеширование страниц целиком - очень частный случай, со множеством ограничений. Кеширование результатов работы методов менеджеров моделей - imho гораздо более широко применимый подход.

  4. Александр

    28.07.2010

    0 ↑
    1 ↓
    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
  5. Александр

    28.07.2010

    0 ↑
    0 ↓
    Михаил Коробов
    Если организовать кеширование фрагментов шаблона то как можно сбросить кеш при изменении записи, то есть какая должна быть функция которая передастся post_save ?
  6. точно такая же: нужно как-то вычислить ключ и вызвать cache.delete

    http://www.google.ru/search?&q=django+template+cache+invalidation

  7. Александр

    29.07.2010

    0 ↑
    0 ↓
    Михаил Коробов

    я вот и пишу потому что не знаю как вычислить ключ. у других людей спрашивал они с помощью cache.set задавали id ключа а потом его удаляли. Как правильно задать id ключа я не знаю. Хотя бы часть кода бы получить чтобы уже самому допилить
  8. сложно найти нужную строчку среди 40 строк middleware?

  9. Александр

    29.07.2010

    0 ↑
    1 ↓
    >сложно найти нужную строчку среди 40 строк middleware?
    эта строка по request.path создает ключ кэша, что делать с теми моделями у которых нету get_absolute_url ?
  10. Причем здесь вообще get_absolute_url? У Вас в кэше есть вьюха, которая выводит один конкретный Second и по нескольку Topik и Files. Соответственно, при сохранении Second можно вычислить URL нужной страницы и удалить ее кэш, а при сохранении топиков и файлов чистить кэш для всех Second (хоть это и неправильно - по-хорошему должно быть одна модель == один элемент в кэше).

  11. Александр

    29.07.2010

    0 ↑
    0 ↓
    >>Соответственно, при сохранении Second можно вычислить URL нужной страницы и удалить ее кэш, а при сохранении топиков и файлов чистить кэш для всех Second

    Каким способом вычисляется url Second, через get_absolute_url ? Я так понял для топиков и файлов нужно сделать выборку к какому они пристыкованы Second и удалить ключ Second по url ?
  12. Каким способом вычисляется url Second, через get_absolute_url ?

    Вы у меня спрашиваете, как в Вашей программе собираются url-ы? :)

    Я так понял для топиков и файлов нужно сделать выборку к какому они пристыкованы Second и удалить ключ Second по url ?

    При Вашей постановке задачи - да. Но, как правильно заметил Михаил, не надо без особой нужды кэшировать страницы целиком, в большинстве случаев на практике такой кэш окажется чуть ли не медленнее, чем вообще никакого из-за постоянной перезаписи.

Внимание! Это довольно старый топик, посты в него не попадут в новые, и их никто не увидит. Пишите пост, если хотите просто дополнить топик, а чтобы задать новый вопрос — начните новый.