Продвинутый Django 5 для продолжающих

Прогресс по курсу:  0/193

10.3 Уровни кэша в Django
7 из 16 шагов пройдено
0 из 27 баллов  получено

Кэширование на основе динамических данных

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

Отредактируйте файл views.py приложения books, видоизменив представление book_list_sort(), приведя его к следующему виду:

@require_http_methods(['GET'])
def book_list_sort(request, filter, direction):
    filter_dict = {_('id'): 'pk',
                   _('title'): 'title',
                   _('author'): 'author',
                   _('price'): 'price',
                   _('read'): 'read'}

    if filter in filter_dict:
        sort_str = ('-', '')[direction == _('ascend')] + filter_dict[filter]
        cache_key = 'cached_book_list_sorted_' + sort_str
        book_list = cache.get_or_set(cache_key, Book.objects.order_by(sort_str))
    else:
        book_list = cache.get_or_set('cached_book_list', Book.objects.all())

    return render(request, 'partial_book_list.html', {'book_list': book_list})

В данном примере мы кэшируем выбранный вариант сортировки списка книг, создав для него имя ключа из параметров сортировки.

Теперь понажимаем на кнопки-стрелки сортировки:

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


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

Для этого создадим в начале файла views.py функцию удаления ключей delete_cache_keys():

def delete_cache_keys():
    cache.delete('cached_book_list')
    for col in ('pk', 'title', 'author', 'price', 'read'):
        cache.delete('cached_book_list_sorted_' + col)
        cache.delete('cached_book_list_sorted_-' + col)

 
И заменим в представлениях строку cache.delete('cached_book_list') на вызов данной функции delete_cache_keys():

@require_http_methods(['POST'])
def create_book(request):
    form = BookCreateForm(request.POST)
    if form.is_valid:
        book = form.save()
        delete_cache_keys()
    return render(request, 'partial_book_detail.html', {'book': book})
def update_book_details(request, pk):
    book = Book.objects.get(pk=pk)
    if request.method == 'POST':
        form = BookEditForm(request.POST, instance=book)
        if form.is_valid():
            book = form.save()
            delete_cache_keys()
            return render(request, 'partial_book_detail.html', {'book': book})
    else:
        form = BookEditForm(instance=book)
    return render(request, 'partial_book_update_form.html', {'book': book, 'form': form})
@require_http_methods(['DELETE'])
def delete_book(request, pk):
    book = get_object_or_404(Book, pk=pk)
    book.delete()
    delete_cache_keys()
    return HttpResponse()
@require_http_methods(['PUT'])
def update_book_status(request, pk):
    book = get_object_or_404(Book, pk=pk)
    if book.read:
        book.read = False
    else:
        book.read = True
    book.save()
    delete_cache_keys()
    return render(request, 'partial_book_detail.html', {'book': book})


Проверим как это работает, после нажатий на кнопки сортировки нажмём кнопку изменить статус любой книги, и после этого увидим 11ть команд delete:


Можно уменьшить количество обращений к кэшу, при удалении, с 11ти до одного, для этого воспользуемся методом delete_many(), перепишем функцию delete_cache_keys():

def delete_cache_keys():
    key_list = ['cached_book_list']
    for col in ('pk', 'title', 'author', 'price', 'read'):
        key_list += ['cached_book_list_sorted_' + col]
        key_list += ['cached_book_list_sorted_-' + col]
    cache.delete_many(key_list)


Теперь видим что выполнилась только одна команда delete_many вместо 11ти команд delete:

Время выполнения обращения к кэшу уменьшилось с 2,4мс до 1,2мс, то-есть в два раза.

Для полной очистки кэша можно воспользоваться методом clear(), он удалит все ключи из кэша.


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