django实现简单的访客日志

时间:2014-08-19 23:09:16

标签: python django logging

我是Django的新手,我正在尝试为我的博客登录访问者。我在博客中使用通用视图,这是代码的一部分:

#blog/urls.py

urlpatterns = patterns('',
    #index
    url(r'^(?P<page>\d+)?/?$', PostListView.as_view(
        model=Post,
        paginate_by=3,
        )),

    #individual post
    url(r'^(?P<pub_date__year>\d{4})/(?P<pub_date__month>\d{1,2})/(?P<slug>[a-zA-Z0-9-]+)/?$', 
        DetailView.as_view(model=Post,)),

    #cat
    url(r'^category/(?P<slug>[a-zA-Z0-9]+)/?$', CategoryListView.as_view(
        paginate_by=3,
        model=Category,
        )),

    #tag
    url(r'^tag/(?P<slug>[a-zA-Z0-9]+)/?$', TagListView.as_view(
        paginate_by=3,
        model=Tag,
        )),

我为访客日志写了一个简单的模型:

#tasks/models.py

class Visitor(models.Model):
    visit_stamp = models.DateTimeField(auto_now_add=True)
    referer = models.CharField(max_length=100, blank=True)
    ip = models.IPAddressField(blank=True)
    user_agent = models.CharField(max_length=100, blank=True)
    page = models.CharField(max_length=100)

及其观点:

#tasks/views.py

def log(request, page):
    try:
        hit = Visitor()
        hit.page = page
        hit.ip = request.META.get('REMOTE ADDR', '')
        hit.last_visit = datetime.now()
        hit.referer = request.META.get('HTTP REFERER', '')
        hit.user_agent = request.META.get('HTTP_USER_AGENT', '')
        hit.save()

    except IntegrityError:
        pass

def tracking(request, page):
    log(request, page)
    return render_to_response(page)

我的问题是如何以及在何处调用此方法,以便我可以记录用户正在访问特定页面。我很感激任何建议。

1 个答案:

答案 0 :(得分:1)

首先,我假设您无法访问apache(或运行您的django应用程序的任何主机)日志和/或您希望最终添加其他内容和/或您希望它在数据库中可用,否则,你可以跳过很多工作,只需要查看日志。

无论如何,我建议重写跟踪以作为装饰工作(并根据需要调整日志...请注意,我相信您可以从请求对象获取URL而不是将其作为页面值传递如果你想知道访问了哪个特定实例)。还有一些方法可以用中间件来做到这一点,但是这为你提供了很好的混合简单性和控制哪些视图被记录的能力。

借用http://www.djangofoo.com/253/writing-django-decorators

的例子
def track(page):
    def decorator(func):
        def inner_decorator(request, *args, **kwargs):
            log(request, page)
            return func(request, *args, **kwargs)
        return wraps(func)(inner_decorator)
    return decorator

然后在你的网址中(或者你也可以用@track来装饰基于功能的视图)

url(r'^(?P<page>\d+)?/?$', track("index")(PostListView.as_view(
        model=Post,
        paginate_by=3,
        ))),
url(r'^someregexp$', track("pagename")(SomeListView.as_view(
        model=Post,
        paginate_by=3,
        ))),

编辑:意味着要添加。请注意,一般来说,GET请求应该是幂等的;日志记录是一个灰色区域,但要记住的主要事情是,如果页面被缓存,某些请求可能无法记录(对于帖子,这不应该是一个问题)