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)