Как считать с фильтром Django запроса? - PullRequest
1 голос
/ 19 марта 2019

Я пытаюсь получить список последних 100 сообщений, а также общее количество утвержденных, ожидающих и отклоненных сообщений для пользователя этого сообщения.

models.py

class BlogPost(models.Model):
    POST_STATUSES = (
    ('A', 'Approved'),
    ('P', 'Pending'),
    ('R', 'Rejected')
    )
    author = models.ForeignKey(User)
    title = models.CharField(max_length=50)
    description = models.TextField()
    status = models.ChoiceField(max_length=1, choices=POST_STATUSES)

views.py

def latest_posts(request)
    latest_100_posts = BlogPost.objects.all()[:100]

Я получаю последние 100 сообщений, теперь я хочу получить каждого автора сообщения и отобразить их общее количество утвержденных, ожидающих, отклоненных сообщений

  • Заголовок сообщения, Автор1, 10, 5, 1
  • Заголовок Поста2, Автор2, 7, 3, 1
  • Заголовок Поста 3, Автор1, 10, 5, 1
  • ...

Некоторые вещи, о которых я думал, - это циклически проходить по каждому из 100 постов и возвращать счетчик, но это кажется очень неэффективным

for post in latest_100_posts:
    approved_count = BlogPost.objects.filter(author=post.user,status='A').count()
    pending_count = BlogPost.objects.filter(author=post.user,status='P').count()
    rejected_count = BlogPost.objects.filter(author=post.user,status='R').count()

Есть ли более эффективный способ сделать это? Я знаю об использовании совокупного количества, но я не уверен, как выполнить суб-фильтрацию статуса ChoiceField

Ответы [ 2 ]

0 голосов
/ 19 марта 2019
from django.db.models import Count

approved_count = BlogPost.objects.filter(author=post.user, status=‘A’).annotate(approved_count=Count(‘id’))
pending_count = BlogPost.objects.filter(author=post.user, status=‘P’).annotate(approved_count=Count(‘id’))
rejected_count = BlogPost.objects.filter(author=post.user, status=‘R’).annotate(approved_count=Count(‘id’))
0 голосов
/ 19 марта 2019

Вы можете сделать это, используя условное агрегирование :

Для этого давайте добавим related_name в BlogPost.

class BlogPost(models.Model):
    POST_STATUSES = (
    ('A', 'Approved'),
    ('P', 'Pending'),
    ('R', 'Rejected')
    )
    author = models.ForeignKey(User, related_name="user_posts")
    title = models.CharField(max_length=50)
    description = models.TextField()
    status = models.ChoiceField(max_length=1, choices=POST_STATUSES)

Затем обновимнабор запросов:

from django.db.models import Count, Case, When, IntegerField

top_post_users = list(BlogPost.objects.values_list('auther_id', flat=True))[:100]
users = User.objects.filter(pk__in=top_post_users).annotate(approved_count=Count(Case(When(user_posts__status="A", then=1),output_field=IntegerField()))).annotate(pending_count=Count(Case(When(user_posts__status="P", then=1),output_field=IntegerField()))).annotate(reject_count=Count(Case(When(user_posts__status="R", then=1),output_field=IntegerField())))

users.values('approved_count', 'pending_count', 'reject_count')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...