Skip to content

Instantly share code, notes, and snippets.

@niran
Created October 14, 2011 22:47
Show Gist options
  • Save niran/1288585 to your computer and use it in GitHub Desktop.
Save niran/1288585 to your computer and use it in GitHub Desktop.
A couple of utility class-based views we use at The Texas Tribune.
from django.http import HttpResponse
from django.shortcuts import redirect
from django.views.generic.detail import BaseDetailView, \
SingleObjectTemplateResponseMixin
from tt.url.unicode import urlencode
class CanonicalUrlBaseDetailView(BaseDetailView):
# If GET parameters are significant, full_path should be True.
full_path = False
def get_object(self):
'''
Returns a redirect HttpResponse or the requested object.
If the requested URL doesn't match the result of the object's
get_absolute_url method, redirect to that URL.
'''
obj = super(CanonicalUrlBaseDetailView, self).get_object()
current_url = self.request.get_full_path() if self.full_path else \
self.request.path
canonical_url = obj.get_absolute_url()
if not current_url.startswith(canonical_url):
if not self.full_path and self.request.GET:
# Preserve GET parameters if they don't affect the object.
canonical_url = '?'.join([canonical_url, urlencode(self.request.GET)])
return redirect(canonical_url, permanent=True)
else:
return obj
def get(self, request, **kwargs):
response_or_object = self.get_object()
if isinstance(response_or_object, HttpResponse):
return response_or_object
self.object = response_or_object
context = self.get_context_data(object=self.object)
return self.render_to_response(context)
class CanonicalUrlDetailView(SingleObjectTemplateResponseMixin,
CanonicalUrlBaseDetailView):
pass
from django.utils.cache import add_never_cache_headers
from django.views.generic.detail import SingleObjectTemplateResponseMixin, \
BaseDetailView
class PreviewBaseDetailView(BaseDetailView):
preview_queryset = None
def is_request_preview(self):
return 'preview' in self.request.GET
def viewer_can_preview(self):
return self.request.user.is_staff
def get_default_queryset(self):
return super(PreviewBaseDetailView, self).get_queryset()
def get_preview_queryset(self):
qs = getattr(self, 'preview_queryset', None)
if qs is None:
qs = self.get_default_queryset()
return qs._clone()
def get_queryset(self):
if self.is_request_preview() and self.viewer_can_preview():
return self.get_preview_queryset()
else:
return self.get_default_queryset()
def get(self, request, **kwargs):
response = super(PreviewBaseDetailView, self).get(request, **kwargs)
if self.is_request_preview():
add_never_cache_headers(response)
return response
class PreviewDetailView(SingleObjectTemplateResponseMixin, PreviewBaseDetailView):
pass
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment