views:

207

answers:

2

I'm new, and confused. I want to create a module that keeps track of the "top hit" instances of both an article and a blog model. I don't want to touch the code for the article or blog models. Is this a candidate for middleware? looking at the HttpRequest.path?

Thanks

+1  A: 

Middleware looking at request.path is ugly, as it introduces a dependency on the details of the URL patterns you use to display articles and blog posts. If you don't mind this coupling, then you might as well just save the performance hit and do your analysis on webserver log files. (EDIT: view middleware would be a better option, as it gives you the view callable and its args. I'd still prefer the decorator approach as it incurs no overhead on unrelated views, but view middleware would work if you don't want to touch the URLconf for the blog/article applications).

I'd use a view decorator that you wrap around the object_detail view (or your custom equivalent). You can do this wrapping directly in the URLconf. Something like this:

def count_hits(func):
    def decorated(request, *args, **kwargs):
        # ... find object and update hit count for it...
        return func(request, *args, **kwargs)
    return decorated

And you can apply it in views.py:

@count_hits
def detail_view(...

or in your URLconf:

url(r'^/blog/post...', count_hits(detail_view))
Carl Meyer
A: 

you could create a generic Hit model

class Hit(models.Model):
    date = models.DateTimeFiles(auto_now=True)
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

in your view.py you write this function:

def render_to_response_hit_count(request,template_path,keys,response):
    for  key in keys:
        for i in response[key]:
             Hit(content_object=i).save()
    return render_to_response(template_path, response)

and the views that you are interested in return

return render_to_response_hit_count(request,   'map/list.html',['list',],
        {
            'list': l,
        })

This approach gives you the power, not only to count the hit, but to filter the hit-history by time, contenttype and so on...

As the hit-table might be growing fast, you should think about a deletion strategy.

Code untested

vikingosegundo