Ved-форум поддержки

Программирование => Django => Тема начата: DigitalMag от Мая 25, 2019, 05:33:57 pm

Название: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Мая 25, 2019, 05:33:57 pm
Есть модель:
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'
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Мая 26, 2019, 10:23:19 am
Пробовал

dialog = Dialogue.objects.get(partakers__in=[recipient, self.request.user])
Получаю
Цитата:
can not resolve partakers into fields
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: AdminUser от Мая 26, 2019, 05:12:40 pm
Можешь сделать так:

dialog = Dialogue.objects.filter(Partakers__id=recipient_id).get(Partakers=self.request.user)
Вернет все беседы, где есть эти собеседники
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Мая 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
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: AdminUser от Мая 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.

Конечно, не самый красивый запрос, но то, что нужно
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Мая 26, 2019, 05:24:50 pm
Спасибо

Переделал на

Dialogue.objects.filter(Partakers__id__in=[buddy_id,self.request.user.id])
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Июня 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]

Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: AdminUser от Июня 01, 2019, 01:26:12 pm
Выбирает все элементы, содержащие buddy_id и self.request.user.id. Во второй строке считает количество участников в элементе с id из этого списка. То есть те, где будет два - это наши клиенты
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Июня 01, 2019, 01:26:55 pm
А если будет несколько диалогов с ними, все они попадут в выборку?
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: AdminUser от Июня 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()
Название: Re: TypeError: int() argument must be a string or a number, not 'list'
Отправлено: DigitalMag от Июня 01, 2019, 01:29:58 pm
Цитата:
Хм. Да. Попробуйте тогда такой вариант:
Пустоту возвращает. Он, видимо, ищет, чтобы recipient_id и sender_id были в одной строке