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
精彩评论