Невозможно установить очень простой атрибут объекта на объект с отношением многие:многие
Я изучаю 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()
.