Фильтр объектов из таблицы на основе поля ManyToMany

Я работаю над приложением для обмена сообщениями. Модели следующие.

class ChatRoom(SafeDeleteModel):
  _safedelete_policy = SOFT_DELETE_CASCADE

  room_name = models.CharField(max_length=100, null=True, blank=True)
  participants = models.ManyToManyField(User)

 class Meta:
    db_table = TABLE_PREFIX + "chat_room"


class Message(SafeDeleteModel):
  _safedelete_policy = SOFT_DELETE_CASCADE

  chat_room = models.ForeignKey(ChatRoom, on_delete=models.CASCADE)
  message = models.TextField()
  sent_by = models.ForeignKey(User, on_delete=models.CASCADE)
  created_on = models.DateTimeField(default=django.utils.timezone.now)

 class Meta:
    db_table = TABLE_PREFIX + "chat_message"

Мне нужно отфильтровать объект ChatRoom, который содержит список пользователей.

Eg: При отправке таких данных в api

{
  "participants": [2,3]
}

Он должен вернуть объект ChatRoom, который содержит пользователя '2' и пользователя '3' в качестве участников.

Я пробовал фильтровать его с помощью

room = ChatRoom.objects.filter(participants__in=serializer.validated_data['participants'])

но возвращает список объектов комнаты с пользователем '1' и пользователем '2'.

Я также пробовал использовать get(), но он возвращает ошибку.

Что я делаю неправильно и как мне сделать это правильно?

Спасибо, что рассмотрели мою проблему. Надеюсь, у вас есть решение.

Вы сказали, что используете Query...

ChatRoom.objects.filter(participants__in=serializer.validated_data['participants'])
  1. filter функция возвращает список объектов модели, соответствующих условиям.
  2. get функция возвращает только один объект модели и если ни один или более одного элемента не соответствует условию, то возникает исключение. Поэтому get используется только для ключей-кандидатов или уникальных результирующих условий.

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

room_list= ChatRoom.objects.filter(participants__in=serializer.validated_data['participants']
if len(room_list) >0:
   room = room_list[0]
else:
   room = None

Это вернет первую комнату, в которой присутствуют все заданные участники, вы можете заменить 0 на любое допустимое значение или добавить что-то еще в запрос, если вы хотите, чтобы он вернул конкретную комнату.

Вернуться на верх