@Egegey

Как правильно отфильтровать Django Queryset и применить annotate?

Я хочу отфильтровать чаты с участием пользователя, который запрашивает эти чаты и каждому чату подсчитать количество участников
class Chat(models.Model):
    users = models.ManyToManyField(User, related_name='chats')


def get_queryset(self):
    return Chat.objects.annotate(user_count=Count('users')).filter(users__id=self.request.user.id)


def get_queryset(self):
    return Chat.objects.filter(users__id=self.request.user.id).annotate(user_count=Count('users'))


Первый метод возвращает такие данные. Они корректные и мне они нужны:
{
        "id": 146,
        "user_count": 2
    },
    {
        "id": 109,
        "user_count": 3
    },
    {
        "id": 22,
        "user_count": 11
    }


Второй возвращает это:
{
        "id": 146,
        "user_count": 1
    },
    {
        "id": 109,
        "user_count": 1
    },
    {
        "id": 22,
        "user_count": 1
    }


Как я понимаю, второй метод лучше, так как я сначала проверяю наличие пользователя в "users", собираю такие чаты и потом им считаю участников.
В первом случае я сначала всем чатам считаю участников (хотя мне не нужны все чаты), а потом фильтрую по наличию пользователя.

Подскажите, почему второй метод считает неверно?
Есть ли разница в скорости этих двух методов?
  • Вопрос задан
  • 217 просмотров
Решения вопроса 1
solotony
@solotony
покоряю пик Балмера
ошибка во втором потому что ты вначале ты фильтром отсекаешь всех остальных пользователей (кроме одного) и считаешь количество для него ожного

разница в скорости будет, если количество участников будет большим.
попробуй так:

def get_queryset(self):
    qs = Chat.objects.filter(users__id=self.request.user.id).values_list('id')
    return Chat.objects.filter(id__in=qs).annotate(user_count=Count('users'))
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы