[Answered ]-Implementing a generic protected preview in Django

2πŸ‘

βœ…

I believe the Django Admin already provides a β€œshow on site” option to the admin pages of any models which provides a get_absolute_url() method. Using decorators, it should be possible to do this in a generic way across models

class MyArticleModel(Article): #extends your abstract Article model
    title = .....
    slug = ......
    body = ......

    @models.permalink
    def get_absolute_url(self): # this puts a 'view on site' link in the model admin page
        return ('views.article_view', [self.slug])

#------ custom article decorator -------------------
from django.http import Http404
from django.shortcuts import get_object_or_404

def article(view, model, key='slug'):
    """ Decorator that takes a model class and returns an instance 
        based on whether the model is viewable by the current user. """
    def worker_function(request, **kwargs):
        selector = {key:kwargs[key]}
        instance = get_object_or_404(model, **selector)
        del kwargs[key] #remove id/slug from view params
        if instance.published or request.user.is_staff() or instance.author is request.user:
            return view(request, article=instance, **kwargs)
        else:
            raise Http404
    return worker_function

#------- urls -----------------

url(r'^article/(?(slug)[\w\-]{10-30})$', article_view, name='article-view'),
url(r'^article/print/(?(id)\d+)$', 
     article(view=generic.direct_to_template,
             model=MyArticleModel, key='id'),
     name='article-print-view'
)

#------ views ----------------
from django.shortcuts import render_to_response

@article(MyArticleModel)
def article(request, article):
    #do processing!

    return render_to_response('article_template.html', {'article':instance}, 
                              xontext_instance=RequestContext(request) )

Hope this is informative (and hopefully correct πŸ˜‰

πŸ‘€Thomas

Leave a comment