I'm trying to implement conditional caching using django.middleware.http.CondtionalGetMiddleware
. I'm able to correctly return 304/200 if I provide an If-None-Match
with ETag
value in the request headers.
However, I'm unable to do so when I provide If-Modified-Since
in the request headers. I believe it is because my response does not contain a header called Last-Modified
, which ConditionalGetMiddleware
seems to be requiring, as follows:
class ConditionalGetMiddleware(MiddlewareMixin):
"""
Handle conditional GET operations. If the response has an ETag or
Last-Modified header and the request has If-None-Match or If-Modified-Since,
replace the response with HttpNotModified. Add an ETag header if needed.
"""
def process_response(self, request, response):
# It's too late to prevent an unsafe request with a 412 response, and
# for a HEAD request, the response body is always empty so computing
# an accurate ETag isn't possible.
if request.method != "GET":
return response
if self.needs_etag(response) and not response.has_header("ETag"):
set_response_etag(response)
etag = response.get("ETag")
last_modified = response.get("Last-Modified")
last_modified = last_modified and parse_http_date_safe(last_modified)
if etag or last_modified:
return get_conditional_response(
request,
etag=etag,
last_modified=last_modified,
response=response,
)
return response
def needs_etag(self, response):
"""Return True if an ETag header should be added to response."""
...
Ideally, I would like Last-Modified
to have a value similar to ConcernedModel.objects.latest("updated_at")
.
One way that comes to mind is to send Last-Modified
in every API response.
Looking for better ideas/any shortcuts, please?