开发者

Limit number of views per day in Django

Is there an easy way to limit the number of times a view can be accessed by a given IP address per day/week? A simplified version of the technique used by some booksellers to limit the number of pages of a book you can preview?

There's only one view that this limit need apply to--i.e. it's not a general limit--and it w开发者_如何学Could be nice if I could just have a variable overlimit in the template context. The solution need not be terribly robust, but limiting by IP address seemed like a better idea than using a cookie.

I've looked into the session middleware but it doesn't make any references to tracking IP addresses as far as I can tell.

Has anyone encountered this problem?


The solution I came up with harnessed the django-hitcount app and a "wrapping" of the original view. Luckily, I have an object (Page) that I can associate with the view I'm trying to limit, so the hitcount app works well (and mostly as intended).

The view I'm tracking is line_list -- so I called the new view to wrap it line_list_monitor and associated the original url for line_list with it. The new view is included below. If the IP in question is over the limit (20 views per week), I redirect to overlimit.html, else the original view just gets called like normal.

def line_list_monitor(request, character, pagenum):
    LIMIT_HITS = 20
    LIMIT_PERIOD = {'weeks': 1}
    obj, created = Page.objects.get_or_create(character=character, page=pagenum)
    obj_pk = obj.pk
    ctype = ContentType.objects.get_for_model(obj)
    hitcount, created = HitCount.objects.get_or_create(content_type=ctype,
                                                          object_pk=obj_pk)
    hit = Hit(session="",
              hitcount=hitcount,
              ip=get_ip(request),
              user_agent="")
    hit.save()
    period = datetime.datetime.utcnow() - datetime.timedelta(**LIMIT_PERIOD)
    count = hitcount.hit_set.filter(ip=get_ip(request),
                                    created__gte=period).count()
    if count > LIMIT_HITS:
        template = "overlimit.html"
        return render_to_response(template, context_instance=RequestContext(request))
    else:
        return line_list(request, character, page)


The HttpRequest object has a META member dictionary, which has a REMOTE_ADDR member, so request.META["REMOTE_ADDR"] should get you the IP address in the view, which can then set overlimit in the context... Is that what you want?


if you are able to define firewall (iptables/netfilter) on your server you can limit the access very easy. a tutorial how this is done can be found at debian administrator. this is an example how to secure the ssh-port, but you can use the same technique for http.

i have all of my servers "secured" like this, and i am very lucky with it.

keep in mind, that if you have ajax-functionality on your site you need much more requests/minute like on non-ajax sites allowed by the firewall

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜