РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
338 of 818 menu

Декоратор last_modified

Декоратор last_modified применяется к функциям представления и позволяет серверу возвращать ответ 304 Not Modified, если запрошенный ресурс не изменился с момента последнего визита клиента. В качестве аргумента декоратор принимает функцию обратного вызова, которая должна возвращать объект типа datetime с датой последнего изменения ресурса.

Синтаксис

from django.views.decorators.http import last_modified @last_modified(get_last_modified) def my_view(request): # Код представления return render(request, 'template.html', context)

Декоратор принимает один обязательный аргумент - функцию, которая вычисляет дату последнего изменения. Эта функция должна принимать те же аргументы, что и представление, и возвращать объект datetime или None, если дата изменения неизвестна.

Пример

Рассмотрим простой пример использования декоратора для представления, которое показывает последнюю статью:

from datetime import datetime from django.shortcuts import render from django.views.decorators.http import last_modified from myapp.models import Article def get_last_modified(request): last_article = Article.objects.latest('updated_at') return last_article.updated_at @last_modified(get_last_modified) def latest_article(request): article = Article.objects.latest('created_at') return render(request, 'article.html', {'article': article})

Когда клиент запрашивает страницу в первый раз, сервер возвращает полный ответ. При повторных запросах браузер отправляет заголовок If-Modified-Since с датой из предыдущего ответа. Декоратор сравнивает эту дату с датой последнего изменения ресурса и, если дата не изменилась, возвращает ответ 304 Not Modified.

Пример

Давайте используем декоратор с дополнительной проверкой пользовательских данных:

from datetime import datetime from django.shortcuts import get_object_or_404, render from django.views.decorators.http import last_modified from myapp.models import Article, UserProfile def get_last_modified(request, article_id): article = get_object_or_404(Article, id=article_id) last_update = article.updated_at if request.user.is_authenticated: profile = get_object_or_404(UserProfile, user=request.user) if profile.last_activity > last_update: last_update = profile.last_activity return last_update @last_modified(get_last_modified) def article_detail(request, article_id): article = get_object_or_404(Article, id=article_id) return render(request, 'article_detail.html', {'article': article})

Результат выполнения кода при повторном запросе без изменений:

"Response status: 304 Not Modified"

В этом примере функция get_last_modified учитывает не только дату обновления статьи, но и время последней активности пользователя. Если пользователь изменил свой профиль, то контент страницы считается изменённым, даже если сама статья не обновлялась.

Пример

Декоратор last_modified можно комбинировать с декоратором etag для более точного контроля кеширования:

from datetime import datetime from django.shortcuts import render from django.views.decorators.http import last_modified, etag from myapp.models import Article def get_last_modified(request): last_article = Article.objects.latest('updated_at') return last_article.updated_at def get_etag(request): last_article = Article.objects.latest('updated_at') return f"article-{last_article.id}-{last_article.updated_at.timestamp()}" @last_modified(get_last_modified) @etag(get_etag) def article_list(request): articles = Article.objects.filter(status='published') return render(request, 'articles.html', {'articles': articles})

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

Пример

Если ресурс может быть изменён в зависимости от пользовательских параметров, таких как язык или регион, можно включить эти параметры в вычисление даты изменения:

from datetime import datetime from django.shortcuts import render from django.views.decorators.http import last_modified from myapp.models import Article, Category def get_last_modified(request, category_slug): category = get_object_or_404(Category, slug=category_slug) articles = Article.objects.filter(category=category) last_article = articles.latest('updated_at') return last_article.updated_at @last_modified(get_last_modified) def category_articles(request, category_slug): category = get_object_or_404(Category, slug=category_slug) articles = Article.objects.filter(category=category, status='published') return render(request, 'category.html', { 'category': category, 'articles': articles, })

Результат выполнения кода при запросе категории без изменений:

"Status: 304 Not Modified" "Content loaded from browser cache"

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

Смотрите также

  • декоратор etag,
    который управляет кешированием через ETag
  • декоратор condition,
    который объединяет проверки по ETag и дате изменения
  • декоратор require_GET,
    который ограничивает доступ к представлению только GET-запросами
  • декоратор gzip_page,
    который сжимает ответ сервера для экономии трафика
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить