Django ManyToMany фильтрация по размеру или члену в наборе

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

class User(models.Model):
    id = models.IntegerField(primary_key=True)
    name = models.CharField(max_length=10)

class Message(models.Model):
    id = models.IntegerField(primary_key=True)
    body = models.CharField(max_length=200)
    users = models.ManyToManyField(User)

Я пытаюсь написать метод утилиты, который для данного пользователя дает мне сообщения, с которыми он (и он один) связан.

то есть для:

m1 = Message(id=1, body='Some body')
m1.save()
m2 = Message(id=2, body='Another body')
m2.save()
m3 = Message(id=3, body='And yet another body')
m3.save()

u1 = User(name='Jesse James')
u1.save()
u2 = User(name='John Doe')
u2.save()

m1.users.add(u1, u2)
m2.users.add(u1)
m3.users.add(u2)

getMessagesFor('Jesse James')

Вернется только m2 .
Предполагая, что у меня в user правильный экземпляр модели, он сводится к одной строке, и я пробовал следующие:

    user.message_set.annotate(usr_cnt=Count('users')).filter(usr_cnt__lte=1)

Или:

    messages = Message.objects.filter(users__id__in=[user.id])

А также:

    messages = Message.objects.filter(users__id__exact=user.id)

А также:

    messages = Message.objects.filter(users__contains=user)

И так далее ... Я всегда получаю как m2 И m1 .
Пробовал аннотации, исключает, фильтрует и т. Д.

Может кто-то помочь мне с этим?

2
nl ja de
пожалуйста, проверьте мой ответ, он должен делать то, что вы ищете
добавлено автор Aamir Adnan, источник

2 ответы

qs = Message.objects.annotate(cc=Count('users')).filter(cc=1)

Над запросом будут возвращены все сообщения, у которых есть только один пользователь, связанный с ним.

Чтобы фильтровать пользователь, добавьте еще один фильтр в конец, чтобы отфильтровать аннотированный запрос в соответствии с пользователем:

qs = Message.objects.annotate(cc=Count('users')).filter(cc=1).filter(users__id=user.id)
# if user user.id=1, this will return only m2
5
добавлено
Спасибо, это сделал трюк, я не понимаю, почему двойная фильтрация делает то, что один (и более интуитивный) нет. Мой первый комментарий был на начальном ответе, тем временем вы его отредактировали.
добавлено автор Ofir Farchy, источник

Что-то вроде этого, может быть? (не испытано)

for msg in Messages.objects.all():
    if (user in msg.users_set.all() and len(msg.users_set.all()) == 1):
        # do something
0
добавлено
Неэффективное решение, это ударит db много раз
добавлено автор Aamir Adnan, источник
Python
Python
7 654 участник(ов)

Уютный чат для профессионалов, занимающихся поиском питоньих мудростей. Как не получить бан: https://t.me/ru_python/577926

Python beginners
Python beginners
4 449 участник(ов)

Вопросы про Python для чайников. Cпам и троллинг неприемлем. Не злоупотребляйте стикерами. Частозадаваемые вопросы: https://github.com/ru-python-beginners/faq/blob/master/README.md Статистика тут: https://grstats.me/chat/x4qym2k5uvfkr3al6at7

Django
Django
1 931 участник(ов)

Полезная информация и правила: https://github.com/django-ru/faq Вакансии и резюме: @django_jobs Пофлудить идём сюда: @django_flood Статистика чата: combot.org/chat/-1001063854692

pro.python
pro.python
1 090 участник(ов)

Сообщество разработчиков под Python Создатель: @rodgelius

Rude Python
Rude Python
971 участник(ов)

Python без „девочек”, здесь матерятся и унижают Django. Not gay friendly. Правила: t.me/rudepython/114107 @rudepython | t.me/rudepython

django_jobs
django_jobs
916 участник(ов)

Поиск и предложения работы (Django) Правила: https://t.me/django_jobs/4 Вакансии с тегом #job улетают в канал @django_jobs_board Вопросы к @amureki Основной чат @pydjango

Django
Django
733 участник(ов)

Веб-фреймворк для перфекционистов с дедлайнами. Наша группа на vk: https://vk.com/django_framework В Discord: https://discord.me/django_framework по всем вопросам @MechanisM

rupython
rupython
509 участник(ов)

Группа создана с целью оперативного получения ответов на возникающие вопросы по разработке на яп python, смежные темы, а также человеческого общения. Приветствую!

Python-programming
Python-programming
266 участник(ов)

Чат группы вконтакте https://vk.com/python_community

django flood
django flood
71 участник(ов)

Флудилка джангистов Пока без правил