Декоратор condition
Декоратор condition применяется к функциям представления и позволяет управлять кэшированием на основе условий ETag и Last-Modified. Он принимает два параметра: etag_func и last_modified_func, которые должны возвращать строку ETag и дату последнего изменения соответственно. Декоратор сравнивает заголовки запроса с вычисленными значениями и при совпадении возвращает ответ 304 Not Modified, что экономит трафик и ускоряет загрузку.
Синтаксис
from django.views.decorators.http import condition
@condition(etag_func=None, last_modified_func=None)
def view_func(request):
# логика представления
return response
Пример
Давайте реализуем представление для отображения статьи с использованием декоратора condition для управления кэшированием:
from django.views.decorators.http import condition
from django.http import HttpResponse
from myapp.models import Article
from datetime import datetime
import hashlib
def get_etag(request, article_id):
article = Article.objects.get(id=article_id)
content = f"{article.title}{article.updated_at}"
return hashlib.md5(content.encode()).hexdigest()
def get_last_modified(request, article_id):
article = Article.objects.get(id=article_id)
return article.updated_at
@condition(etag_func=get_etag, last_modified_func=get_last_modified)
def article_detail(request, article_id):
article = Article.objects.get(id=article_id)
return HttpResponse(f"Article: {article.title}")
При повторном запросе той же статьи сервер вернёт ответ 304 Not Modified, если статья не изменилась:
"Response status: 304 Not Modified"
Пример
Рассмотрим пример использования декоратора condition с одной функцией вычисления ETag:
from django.views.decorators.http import condition
from django.http import JsonResponse
from myapp.models import Article
import hashlib
def article_etag(request, article_id):
article = Article.objects.get(id=article_id)
content = f"{article.title}{article.content}"
return hashlib.sha256(content.encode()).hexdigest()
@condition(etag_func=article_etag)
def article_json(request, article_id):
article = Article.objects.get(id=article_id)
data = {"title": article.title, "content": article.content}
return JsonResponse(data)
Если ETag совпадает с заголовком If-None-Match запроса, Django автоматически вернёт ответ 304 Not Modified:
"Response: 304 Not Modified (cached)"
Пример
Использование декоратора condition только с функцией вычисления даты последнего изменения:
from django.views.decorators.http import condition
from django.http import HttpResponse
from myapp.models import Article
from datetime import datetime
def get_last_modified(request, article_id):
article = Article.objects.get(id=article_id)
return article.updated_at
@condition(last_modified_func=get_last_modified)
def article_view(request, article_id):
article = Article.objects.get(id=article_id)
return HttpResponse(f"<h1>{article.title}</h1><p>{article.content}</p>")
При запросе с заголовком If-Modified-Since сервер возвращает 304 Not Modified, если статья не обновлялась:
"HTTP/1.1 304 Not Modified"
Пример
Комбинированное использование condition с обеими функциями для максимальной эффективности кэширования:
from django.views.decorators.http import condition
from django.http import HttpResponse
from myapp.models import Article
from datetime import datetime
import hashlib
def get_etag(request, article_id):
article = Article.objects.get(id=article_id)
return hashlib.md5(article.content.encode()).hexdigest()
def get_last_modified(request, article_id):
article = Article.objects.get(id=article_id)
return article.updated_at
@condition(etag_func=get_etag, last_modified_func=get_last_modified)
def article_secure(request, article_id):
article = Article.objects.get(id=article_id)
return HttpResponse(f"Article secure: {article.title}")
При выполнении запроса сервер проверит оба условия и при совпадении вернёт 304 Not Modified:
"Status: 304 Not Modified (both ETag and Last-Modified match)"
Смотрите также
-
декоратор
etag,
который управляет кэшированием только через ETag -
декоратор
last_modified,
который управляет кэшированием только через дату изменения -
класс
HttpResponseNotModified,
который возвращает ответ 304 без содержимого -
декоратор
gzip_page,
который сжимает ответ для экономии трафика