Удалите дубликаты, где content_id и ip_address совпадают. В модуле Python django - PullRequest
1 голос
/ 13 июня 2019

У меня есть некоторые настройки кода для подсчета кликов на странице, данные сохраняются в модели ObjectViewed при каждом нажатии на страницу.В настоящее время я подсчитываю, сколько раз была нажата каждая страница, но я бы хотел, чтобы на ней были уникальные клики, поэтому показывать только 1 клик на страницу для каждого IP-адреса.

Я пытаюсь отфильтровать, где ip_address и content_object появляются вместе в строке, более одного раза.

class ObjectViewed(models.Model):
    object_id       = models.PositiveIntegerField()
    content_type    = models.ForeignKey(ContentType, on_delete=models.SET_NULL, null=True)

#where these are together i want to only count once below
    content_object  = GenericForeignKey('content_type', 'object_id')
    ip_address      = models.CharField(max_length=120, blank=True, null=True)


def analytics(request):
    objects = ObjectViewed.objects.all()
    q = NewsPost.objects.values('id').distinct()
    dict = {}

    for object in q:
        dict.update({list(object.values())[0]: 0})
        count = ObjectViewed.objects.values('object_id').annotate(c=Count('object_id')).order_by('-c')

Пробовал несколько вещей, но плохо знакомых с python и django, так что я не совсем уверен, как лучше.Любая помощь / руководство будет оценено, спасибо!

1 Ответ

0 голосов
/ 13 июня 2019

Я думаю, что вы делаете здесь слишком сложно, и, вероятно, вы слишком много работаете сами.

Вы можете посчитать количество различных ip_address es с параметром distinct=True объекта Count [Django-doc], как:

from django.db.models import Count

ObjectViewed.objects.values('object_id', 'content_type').annotate(
    c=Count(<b>'ip_address', distinct=True</b>)
).order_by('-c')

Мы можем использовать это, чтобы эффективно упорядочить наши NewsPost как:

from django.contrib.contenttypes.models import ContentType
from django.db.models import Count

views = <b>dict(</b>ObjectViewed.objects.filter(
    content_type=get_object_for_this_type(NewsPost)
).values_list('object_id').annotate(
    c=Count(<b>'ip_address', distinct=True</b>)
).order_by('object_id')<b>)</b>

тогда мы можем упорядочить элементы на уровне Django / Python, например:

<b>my_newsposts = sorted(</b>NewsPost.objects.all()<b>, key=views.get, reverse=True)</b>

Таким образом, здесь мы сначала фильтруем, чтобы получить только отдельные представления для NewsPost объектов, мы помещаем их в словарь с именем views, затем мы сортируем NewsPost объекты с этими представлениями в обратном порядке. заказ.

...