Django: подсчет каждого одинакового значения в object.filter

У меня есть модель CourseEmailPersonEven, которая имеет следующее:

class CourseEmailPersonEvent(models.Model):
uid = models.UUIDField(primary_key=True, default=uuid.uuid4)

action = models.CharField(max_length=32)
is_filtered = models.BooleanField(default=False)

user_agent = models.CharField(max_length=255, null=True, blank=True)
ip = models.GenericIPAddressField(null=True, blank=True)
ip_address = models.ForeignKey(Ip, on_delete=models.SET_NULL, null=True, blank=True)

created_at = models.DateTimeField(auto_now_add=True)
course_email_person = models.ForeignKey(
    CourseEmailPerson, related_name="events", on_delete=models.CASCADE
)

В наборе представлений (retrieve) я получаю информацию CourseEmailPersonEvent об одном единственном аккаунте. Но я хочу добавить количество одинаковых "ip_address", используемых с каждого аккаунта (даже с моего). И я не знаю, что делать:

class UtilsViewSet(viewsets.ViewSet):

@action(detail=False, methods=["get"], url_path="emails/events/ips")
def emails_events_ip(self, request, *args, **kwargs):

    account = get_object_or_404(models.Account, uid=self.kwargs["account_pk"])

    ips_events_count = (
        models.CourseEmailPersonEvent.objects.filter(
            course_email_person__account=account,
            action="open",
            ip_address__isnull=False,
        )
        .values("ip_address")
        .annotate(Count("ip_address"))
        .order_by("-ip_address__count")
    )

    return Response(ips_events_count)

Вот результат, который я хочу получить в финале: (добавить эту строку "ip_address_used_all_account")

[
{
    "ip_address": "4ead446d-28c5-4641-b44d-f1e3aa7d26f8",
    "ip_address__count": 1,
    "ip_address_used_all_account: 2,
}
]

Насколько велика эта таблица? Насколько интенсивно используется это представление?

Подход "грубой силы" заключается в том, что после того, как вы определили, какой объект ip вас интересует, сделайте отдельный запрос для подсчета использований. Если я правильно понял вашу модель,

ip_address_used_all_account = CourseEmailPersonEvent.filter( ip_address = ip 
    ).count()

Если нет очевидных проблем с производительностью при таком подходе, просто сохраняйте простоту!

Попробуйте это:

class UtilsViewSet(viewsets.ViewSet):
   @action(detail=False, methods=["get"], url_path="emails/events/ips")
   def emails_events_ip(self, request, *args, **kwargs):
      account = get_object_or_404(models.Account, uid=self.kwargs["account_pk"])
      ips = models.CourseEmailPersonEvent.objects.filter(course_email_person__account=account, action="open", ip_address__isnull=False).values_list("ip_address")
      ips_events_count = models.CourseEmailPersonEvent.objects.filter(ip_address__in=ips).values('ip_address').annotate(Count('ip_address'))
      return Response(ips_events_count)
Вернуться на верх