【问题标题】:django implementing simple vistor logdjango 实现简单的访问者日志
【发布时间】:2014-08-19 23:09:16
【问题描述】:

我对 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)

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

【问题讨论】:

    标签: python django logging


    【解决方案1】:

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

    无论如何,我建议重写 track 以用作装饰器(并根据需要调整日志...请注意,我相信您可以从请求对象获取 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 请求应该是幂等的;日志记录是一个灰色区域,但要记住的主要事情是,如果页面被缓存,某些请求可能不会像您预期的那样被记录(对于帖子,这应该不是问题)

    【讨论】:

    • 实际上 url 部分让我更加困惑:|。我采用了一种不同的方法,即为所有模型创建通用对象,并在get_context_data 创建访问者模型,以便每次用户访问时都会创建任何页面日志。这是个坏主意吗?
    • 我个人不喜欢继承你的代码,因为至少我对它如何工作的印象,这违反了 Django 的许多设计理念 (docs.djangoproject.com/en/dev/misc/design-philosophies)。请注意,您甚至可以争辩说我的方式有点违反 DRY(不要重复自己),但是如果您真的想记录每个请求,您可能希望将其作为中间件来执行,而我不必这样做,所以我不能提供很好的例子。
    • 另一方面,我开始使用 Django 进行开发,然后领导学习 Django 的人的经验是,人们一开始做的事情很艰难,随着他们深入了解(深入理解)Django 的哲学,他们可以重构东西
    猜你喜欢
    • 1970-01-01
    • 2016-08-11
    • 1970-01-01
    • 2017-12-17
    • 2014-09-04
    • 1970-01-01
    • 2012-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多