Автор Тема: TypeError: int() argument must be a string or a number, not 'list'  (Прочитано 2500 раз)

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Есть модель:
class Dialogue(models.Model):
    Partakers = models.ManyToManyField(Profile, related_name='partakers')

Пытаюсь сделать выборку по Partakers
        dialog = Dialogue.objects.get_or_create(Partakers=[recipient_id,self.request.user.id])
Но получаю
Цитата:
TypeError: int() argument must be a string or a number, not 'list'

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #1 : Мая 26, 2019, 10:23:19 am »
Пробовал

dialog = Dialogue.objects.get(partakers__in=[recipient, self.request.user])
Получаю
Цитата:
can not resolve partakers into fields
« Последнее редактирование: Мая 26, 2019, 10:38:30 am от DigitalMag »

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #2 : Мая 26, 2019, 05:12:40 pm »
Можешь сделать так:

dialog = Dialogue.objects.filter(Partakers__id=recipient_id).get(Partakers=self.request.user)
Вернет все беседы, где есть эти собеседники
« Последнее редактирование: Мая 26, 2019, 05:20:00 pm от AdminUser »

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #3 : Мая 26, 2019, 05:19:41 pm »
Спасибо.

Но мне нужно не просто все беседы, где есть эти собеседники, а беседу, в которой есть ТОЛЬКО эти собеседники.

Пробовал даже через Q-objects:

dialog = Dialogue.objects.filter(Q(Partakers__id=recipient_id), Q(Partakers__id=self.request.user.id))
пробовал отталкиваться от конкретного юзера:

dialog = self.request.user.dialogs.filter(Partakers=recipient)
Но получаю пустой кверисет

Запрос формируется такой:

SELECT ••• FROM "main_dialogue" INNER JOIN "main_dialogue_Partakers" ON ("main_dialogue"."id" = "main_dialogue_Partakers"."dialogue_id") WHERE ("main_dialogue_Partakers"."profile_id" = '20' AND "main_dialogue_Partakers"."profile_id" = '7') LIMIT 21

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #4 : Мая 26, 2019, 05:23:36 pm »
Этот запрос пытается одновременно найти в таблицы запись у которой profile_id=7 и одновременно 20,что невозможно.

Короче, какой вариант могу предложить

        partakers = chain(Profile.objects.none(),[Profile.objects.get(id=buddy_id),self.request.user])
        dialogs = Dialogue.objects.filter(Partakers__in=partakers).annotate(num_partekers=Count('Partakers'))
        dialogs = [dialog for dialog in dialogs if dialog.num_partekers == 2]

        print dialogs

По идее должно получиться как раз то, что вы хотите

Или попробуйте подобный фокус провернуть с запросом из моего предыдущего ответа: то есть выбрать диалог с количеством собеседников = 2.

Конечно, не самый красивый запрос, но то, что нужно

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #5 : Мая 26, 2019, 05:24:50 pm »
Спасибо

Переделал на

Dialogue.objects.filter(Partakers__id__in=[buddy_id,self.request.user.id])

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #6 : Июня 01, 2019, 01:14:10 pm »
У меня тут возник вопрос на засыпку. Что делает этот запрос?

        dialogs = Dialogue.objects.filter(Partakers__in__id=[buddy_id,self.request.user.id])
        dialogs  = dialogs .annotate(num_partekers=Count('Partakers'))
        dialogs = [dialog for dialog in dialogs if dialog.num_partekers == 2]

« Последнее редактирование: Июня 01, 2019, 01:24:12 pm от AdminUser »

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #7 : Июня 01, 2019, 01:26:12 pm »
Выбирает все элементы, содержащие buddy_id и self.request.user.id. Во второй строке считает количество участников в элементе с id из этого списка. То есть те, где будет два - это наши клиенты

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #8 : Июня 01, 2019, 01:26:55 pm »
А если будет несколько диалогов с ними, все они попадут в выборку?

AdminUser

  • Team Lead
  • Юный джедай
  • *****
  • Сообщений: 65
  • Репутация +8/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #9 : Июня 01, 2019, 01:28:26 pm »
Хм. Да. Попробуйте тогда такой вариант:

        dialogs = Dialogue.objects.filter(Partakers__id=recipient_id).filter(Partakers__id=sender_id)
        dialogs = dialogs.annotate(num_partekers=Count('Partakers'))
        dialogs = [dialog for dialog in dialogs if dialog.num_partekers == 2]
        dialog = dialogs.pop()

DigitalMag

  • Юный джедай
  • **
  • Сообщений: 89
  • Репутация +6/-0
    • Просмотр профиля
Re: TypeError: int() argument must be a string or a number, not 'list'
« Ответ #10 : Июня 01, 2019, 01:29:58 pm »
Цитата:
Хм. Да. Попробуйте тогда такой вариант:
Пустоту возвращает. Он, видимо, ищет, чтобы recipient_id и sender_id были в одной строке