如何在Django App中通过Mixins跟踪ListView,其他视图和URL

时间:2019-04-18 19:44:43

标签: python django analytics mixins

朋友

我有一个Django应用,我想为我的所有视图添加一些基本跟踪。 (很像柜台或类似的东西)

到目前为止,我可以使用mixin跟踪特定的对象。因此,每当有人单击我的模型实例(DetailView)时,都会向我的数据库添加一个条目。我是通过django内容类型完成的。

现在,要执行此操作,我需要一个get方法才能实际取回特定对象。

但是在我的ListView中,我没有那个对象。

如何为URL或仅为ListView实现类似的东西?那有可能吗?我想记录一个条目,说明已经访问了我的模型列表。

这是我到目前为止所拥有的:

我的观点

class ListJobView(ObjectViewMixin, ListView):
    model = Job
    context_object_name = 'jobs'
    template_name = 'list_jobs.html'
    ordering = '-pub_date'
    # paginate_by = 1

class DetailJobView(ObjectViewMixin, DetailView):
    model = Job
    template_name = 'detail_job.html'
    queryset = Job.objects.all()

    def get_object(self):
        id = self.kwargs.get("id")
        return get_object_or_404(Job, id=id)

我的混蛋

from .signals import object_viewed_signal

class ObjectViewMixin:
    def dispatch(self, request, *args, **kwargs):
        try:
            instance = self.get_object()
        except self.model.DoesNotExist:
            instance = None

        if instance is not None:
            object_viewed_signal.send(instance.__class__, instance=instance, request=request)


        return super(ObjectViewMixin, self).dispatch(request, *args, **kwargs)

我的信号

from django.dispatch import Signal

object_viewed_signal = Signal(providing_args=['instance', 'request'])

这是信号处理程序:


    def object_viewed_receiver(sender, instance, request, *args, **kwargs):
        new_viewed_object = ObjectViewed.objects.create(
            user         = request.user,
            content_type = ContentType.objects.get_for_model(sender),
            object_id   = instance.id,
        )

    object_viewed_signal.connect(object_viewed_receiver)

如果我应该提供更多代码,请告诉我。

我们非常感谢您的帮助...

1 个答案:

答案 0 :(得分:1)

因此,此答案无任何保证。我在问这个问题时就实施了该解决方案,但是由于我从Django应用程序中删除了此功能,因此不再使用它。其原因是沉重的负担。因为在此解决方案中,我为每次有人访问该网站时创建一个对象并将其保存到数据库中。效果很好,但过一会儿对于数据库来说真的很沉重。

首先,我创建了一个新应用,并将其命名为analytics。在应用程序中,我创建了这样的模型:

class UrlTime(models.Model):
    associated_url = models.CharField(blank=True, null= True, max_length=250)
    timestamp = models.DateTimeField(auto_now=True, blank=True)

    def __str__(self):
        return self.associated_url

我创建了一个名为middleware.py的新模块。中间件基本上在调用视图之前或在调用视图之后执行代码(取决于代码的放置位置)。如果您计算URL,我认为在调用视图之前拥有URL是很好的:

middleware.py

from .models import UrlTime

class GetUrlMiddleware():
    def __init__(self, get_response):
        self.get_response = get_response

    def __call__(self, request):
        # before view
        # creates a counter object for URL if url doesn't exist. Else counts up.
        if request.path.startswith('/admin/'):  ##exclude what you don't want to count
            pass
        else:
            # urltrack, _ = UrlTrack.objects.get_or_create(url=request.path)
            # urltrack.counter = F('counter') + 1
            # urltrack.save()

            urltime = UrlTime.objects.create(associated_url=request.path)
            urltime.save()

        response = self.get_response(request)
        # after view

        return response

有了这个,您应该能够在每次有人访问该页面时计算您的URls。将在数据库中创建一个对象。然后,您只需要在模板上按需要显示它即可。我做了这样的事情:


class AnalyticsIndexView(StaffRequiredMixin, ListView):
    template_name = 'analytics_list.html'
    model = UrlTime

    def get_context_data(self, **kwargs):
        context = super(AnalyticsIndexView, self).get_context_data(**kwargs)
        context['object_viewed_list'] = ObjectViewed.objects.all()
        context['url_views_list'] = UrlTime.objects.all()
        context['total_views'] = UrlTime.objects.all().count
        counting = UrlTime.objects.all().values('associated_url').annotate(url_count=Count('associated_url'))
        context['home_view'] = counting
        context['start'] = UrlTime.objects.first()

        return context

然后,您只需要实现模板即可。...如果您也需要此信息,请告诉我,我也将其发布在这里。