Невозможно установить очень простой атрибут объекта на объект с отношением многие:многие

Я изучаю django и, похоже, не могу просто буквально добавить сообщение в автоматизацию. У меня есть метод POST, и я должен иметь возможность добавить сообщение в автоматизацию (классы Message и Automation имеют отношения "многие ко многим").

Таким образом автоматизация регистрируется непосредственно перед попыткой добавить сообщение:

before {'_state': <django.db.models.base.ModelState object at 0x7fbd47a27370>, 'id': 9, 'name': 'test bobbie automation', 'description': 'a test bobbie automation', 'account_id': 34, 'date_created': datetime.datetime(2021, 8, 27, 8, 55, 52, 723100, tzinfo=<UTC>)}

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

Что я делаю не так? Я пробовал все эти варианты, но безрезультатно:

    # automation.messages.set(msg) 
    # automation.messages.append(msg)
    # automation.messages.add(msg)  # does not work
    # automation['messages'] = msg
    automation.messages.set(msg)

После последней попытки происходит ошибка TypeError: 'Message' object is not iterable.

Вид:

@login_required(login_url='login')
@allowed_users(allowed_roles=['admin', 'customer'], own_account_only=True)
def automation_add_message(request, pk, automation_id):
    account = Account.objects.get(id=pk)
    automation = Automation.objects.get(id=automation_id)

    if request.method == 'POST':
        msgId = request.POST.get('message_id')
        msg = Message.objects.get(id=msgId)
        print('before', automation.__dict__)
        # automation.messages.set(msg)  # error here @todo
        # automation.messages.append(msg)
        # automation.messages.add(msg)  # does not work
        # automation['messages'] = msg
        # also fails with TypeError: 'Message' object is not iterable
        automation.messages.set(msg)
        print('after', automation.__dict__)
        automation.save()
        print('saved')
        redirect_url = '/accounts/' + pk + '/automations'
        return redirect(redirect_url)

Модели:

class Automation(models.Model):
    name = models.CharField(max_length=100)
    description = models.CharField(max_length=200)
    account = models.ForeignKey(Account, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    messages = models.ManyToManyField(Message, blank=True)

    def __str__(self):
        return self.name


class Message(models.Model):
    name = models.CharField(max_length=100)
    subject = models.CharField(max_length=128)
    text = models.TextField()
    account = models.ForeignKey(Account, on_delete=models.CASCADE)
    date_created = models.DateTimeField(auto_now_add=True, null=True)
    automations = models.ManyToManyField('automations.Automation', blank=True)

    def __str__(self):
        return self.name

Возможно, это легко исправить...

Для метода .set(…) нужно передать итерабельность элементов, например, список:

automation.messages.set([msg])

Однако это не добавит msg к сообщениям объекта automation, это удалит все элементы и добавит msg.

Если вы хотите добавить msg к .messages из automation, вы работаете с:

automation.messages.add(msg)

Кроме того, нет необходимости сохранять объект automation, поскольку ManyToManyField работает со "скрытой" моделью, поэтому можно удалить вызов метода automation.save().

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