def etag_request_processor(self, request): # XXX is this a performance concern? Does it create a new class # every time the processor is called or is this optimized to a static # class?? class DummyResponse(dict): """ This is a dummy class with enough behaviour of HttpResponse so we can use the condition decorator without too much pain. """ def has_header(self, what): return False def dummy_response_handler(*args, **kwargs): return DummyResponse() def etagger(request, page, *args, **kwargs): etag = page.etag(request) return etag # Unavailable in Django 1.0 -- the current implementation of ETag support # requires Django 1.1 unfortunately. from django.views.decorators.http import condition # Now wrap the condition decorator around our dummy handler: # the net effect is that we will be getting a DummyResponse from # the handler if processing is to continue and a non-DummyResponse # (should be a "304 not modified") if the etag matches. rsp = condition(etag_func=etagger)(dummy_response_handler)(request, self) # If dummy then don't do anything, if a real response, return and # thus shortcut the request processing. if not isinstance(rsp, DummyResponse): return rsp
def get_conditional_response(self, *args, **kwargs): return condition( self.etag_func, self.last_modified_func )(super(self.__class__, self).dispatch)( *args, **kwargs )
def buildfeed(request, feedclass, **criterias): 'View that handles the feeds.' view_data = initview(request) wrap = lambda func: ft.partial(func, _view_data=view_data, **criterias) return condition( etag_func=wrap(cache_etag), last_modified_func=wrap(cache_last_modified) )\ (_buildfeed)(request, feedclass, view_data, **criterias)
def mainview(request, **criterias): 'View that handles all page requests.' view_data = initview(request) wrap = lambda func: ft.partial(func, _view_data=view_data, **criterias) return condition( etag_func=wrap(cache_etag), last_modified_func=wrap(cache_last_modified) )\ (_mainview)(request, view_data, **criterias)
def get_handler(self, request): handler = super().get_handler(request) if handler and self.method in ('get', 'head'): return condition( last_modified_func=self._last_modified, etag_func=self.etag, )(handler) else: return handler
def get_allow_handler(self): """ If either of condition_etag or condition_last_modified is defined, wrap the base allow handler in the condition() decorator. """ allow = super(Condition, self).get_allow_handler() if (isinstance(self.condition_etag, collections.Callable) or isinstance(self.condition_last_modified, collections.Callable)): allow = http.condition( etag_func=self.condition_etag, last_modified_func=self.condition_last_modified)(allow) return allow
class RemoteBaseView(LockView): """ Remote base view is not intended to be used as a real view, this is just the base implementation view to be inherited with a remote mixin """ @method_decorator(condition(last_modified_func=last_modified_condition)) def get(self, request, *args, **kwargs): messages = self.get_backend() if self.http304_if_empty and len(messages) == 0: return HttpResponseNotModified(content_type=self.mimetype) backend = self.build_backend(messages) return self.patch_response( http.HttpResponse(backend, content_type=self.mimetype) )
class CachedView(object): @method_decorator(cache_page(1)) @method_decorator( condition(etag_func=etag_func, last_modified_func=latest_access)) def get(self, request, *args, **kwargs): import rfc822 import time rv = super(CachedView, self).get(request, *args, **kwargs) if not request.user.is_anonymous(): utils.cache.patch_cache_control(rv, private=True) etag = get_etag_key(request) if etag: rv['ETag'] = etag return rv
class HashtagListView(ErrorsMixin, mixins.ListModelMixin, generics.GenericAPIView): serializer_class = HashtagListSerializer queryset = selectors.get_hashtags() pagination_class = None expected_exceptions = {} permission_classes = [permissions.AllowAny] search_fields = ["slug"] filter_backends = [filters.SearchFilter] def get_queryset(self): return annotations.annotate_company_count(selectors.get_hashtags()) @method_decorator(cache_control(max_age=60)) @method_decorator(condition(last_modified_func=caching.hashtag_last_modified)) def get(self, request): return super().list(request)
class CompanyDetailView( ErrorsMixin, mixins.RetrieveModelMixin, generics.GenericAPIView, ): serializer_class = ResponseCompanyDetailSerializer queryset = selectors.get_companies() expected_exceptions = {} lookup_field = "slug" permission_classes = [permissions.IsAuthenticatedOrReadOnly] def get_queryset(self): user = self.request.user qs = selectors.get_companies().select_related("created_by__avatar", "created_by__user") if user.is_authenticated: qs = annotations.annotate_company_claps(qs, profile_id=user.profile.id) return qs @method_decorator( condition(last_modified_func=caching.company_last_modified)) def get(self, request, slug): return super().retrieve(request, slug)
def as_view(cls, **initkwargs): view = super(RawDatastreamView, cls).as_view(**initkwargs) # wrap view with conditional decorator for etag/last-modified return condition(etag_func=cls.etag, last_modified_func=cls.last_modified)(view)
def _inner(*args, **kwargs): result = functions[0](*args, **kwargs) for f in functions[1:]: result = f(result) return result return _inner full_decorator = compose( # django.views.decorators.http require_http_methods(["GET"]), require_GET, require_POST, require_safe, condition(lambda r: None, lambda r: None), # django.views.decorators.vary vary_on_headers('Accept-language'), vary_on_cookie, # django.views.decorators.cache cache_page(60 * 15), cache_control(private=True), never_cache, # django.contrib.auth.decorators # Apply user_passes_test twice to check #9474 user_passes_test(lambda u: True), login_required, permission_required('change_world'),
def streaming_response(view): # TODO: Transactions? Gzip? others? return condition(etag_func=None, last_modified_func=None)(view)
def __call__(self, request, *args, **kwargs): wrapper = condition(etag_func=package_etag, last_modified_func=package_last_modified) return wrapper(super(PackageFeed, self).__call__)(request, *args, **kwargs)
# -*- coding:utf-8 -*- from django.views.decorators.http import condition, etag, last_modified from django.http import HttpResponse from models import FULL_RESPONSE, LAST_MODIFIED, ETAG def index(request): return HttpResponse(FULL_RESPONSE) index = condition(lambda r: ETAG, lambda r: LAST_MODIFIED)(index) def last_modified_view1(request): return HttpResponse(FULL_RESPONSE) last_modified_view1 = condition(last_modified_func=lambda r: LAST_MODIFIED)(last_modified_view1) def last_modified_view2(request): return HttpResponse(FULL_RESPONSE) last_modified_view2 = last_modified(lambda r: LAST_MODIFIED)(last_modified_view2) def etag_view1(request): return HttpResponse(FULL_RESPONSE) etag_view1 = condition(etag_func=lambda r: ETAG)(etag_view1) def etag_view2(request): return HttpResponse(FULL_RESPONSE) etag_view2 = etag(lambda r: ETAG)(etag_view2)
def latest_pass(request, pass_type_id, serial_number): return Pass.objects.get(pass_type_identifier=pass_type_id, serial_number=serial_number).updated_at @condition(last_modified_func=latest_pass)
from .models import Post def latest_post(request, *args, **kwargs): return Post.objects.latest().modified_on def get_etag(request, *args, **kwargs): post_modified_on = str(latest_post(request, *args, **kwargs)) return hashlib.md5( "-".join(('blog', post_modified_on)).encode('utf-8') ).hexdigest() @method_decorator( condition(last_modified_func=latest_post, etag_func=get_etag), name='get' ) class PostListView(ListView): """Base Post List View.""" context_object_name = 'posts' model = Post template_name = 'hermes/post_list.html' def get_queryset(self): return self.model.objects.published() class CategoryPostListView(PostListView): """Displays posts from a specific Category""" def get_queryset(self):
def __call__(self, request, *args, **kwargs): wrapper = condition(last_modified_func=removal_last_modified) return wrapper(super(PackageUpdatesFeed, self).__call__)(request, *args, **kwargs)
def __call__(self, request, *args, **kwargs): wrapper = condition(last_modified_func=news_last_modified) return wrapper(super(NewsFeed, self).__call__)(request, *args, **kwargs)
@redis_exception_handler def static_etag(*args, **kwargs): r = TxRedisMapper() return r.get(STATIC_CACHE_KEY_ETAG) @redis_exception_handler def static_last_modified(*args, **kwargs): r = TxRedisMapper() return r.get(STATIC_CACHE_KEY_LAST_MODIFIED) cached_direct_to_template = condition(last_modified_func=static_last_modified, etag_func=static_etag)( direct_to_template ) def log_skip_transaction_test(msg): if not settings.DATABASES["default"]["ENGINE"].endswith("postgresql_psycopg2"): logger.info(msg) return msg def get_url_pattern(urlname, args=[]): """ Return URL pattern for a URL based on its name. args - list of argument names for the URL. Useful to distinguish URL patterns identified with the same name.