drf-extensions
drf-extensions copied to clipboard
Mixin for last-modified header
There is a mixin for etags, which is really useful, but in many cases it would be better to deal with caching based on a date. In a lot of our data, we store the last time something was modified which means we would be able to use the last-modified
header for caching purposes.
Why can't you use Etags for caching purposes?
from rest_framework_extensions.key_constructor.constructors import (
DefaultKeyConstructor
)
from rest_framework_extensions.etag.mixins import ETAGMixin
from yourapp.models import User
from yourapp.serializers import UserSerializer
class LastModifiedKeyBit(KeyBitBase):
def get_data(self, view_instance, view_method, request, args, kwargs):
return view_instance.get_object().last_modified
class CustomKeyConstructor(DefaultKeyConstructor):
last_modified = LastModifiedKeyBit()
class UserViewSet(ETAGMixin, viewsets.ModelViewSet):
serializer_class = UserSerializer
queryset = User.objects.all()
object_etag_func = CustomKeyConstructor()
@kevin-brown, any thoughts? Please, reply, or i'll close this issue.
There are two reasons why I prefer using Etag
alongside a Last-Modified
header:
- When storing data in other devices (such as mobile), not all API clients are going to save the Etag that was returned with the request. Most of the time the last modified time will be available, as it would typically match a field in the body of the response.
- While Etags are a strong validator for caching, and the
Last-Modified
header is a weaker one, it can still help validate requests. This is part of the reason why GitHub returns aLast-Modified
header for some requests, but anEtag
header for all of them.
The main problem with implementing this on a generic level comes down to naming, as not everyone uses a last_modified
field. Dealing with list endpoints is also another issue which I haven't totally considered.
@kevin-brown do you feel to send a PR?