【问题标题】:ValueError: "<Notification: Notification object>" needs to have a value for field "notification" before this many-to-many relationship can be usedValueError: "<Notification: Notification object>" 需要有一个字段 "notification" 的值才能使用这种多对多关系
【发布时间】:2016-12-13 12:26:30
【问题描述】:

我有这个模型:

class Notification(BaseTimestampableModel):
# TYPES CONSTANTS HERE
# TYPE_CHOICES DICT HERE

    sender = models.ForeignKey(User, related_name='sender_notifications')
    receivers = models.ManyToManyField(User, related_name='receiver_notifications')
    type = models.PositiveSmallIntegerField(choices=TYPE_CHOICES)
    data = models.TextField()
    sent = models.BooleanField(default=False)

    class Meta:
       verbose_name = _('Notification')
       verbose_name_plural = _('Notifications')


    def send(self):
        # Logic for sending notification here

        self.sent = True
        self.save()

另一方面,我有这个“静态”类:

class ChatNotifications:
    @staticmethod
    def message_created(message, chat):
        """
        Send a notification when a chat message is created
        to all users in chat except to the message's sender.
        """
        sender = message.user

        data = {
            'text': message.text,
            'phone': str(sender.phone_prefix) + str(sender.phone),
            'chatid': chat.uuid.hex,
            'time': timezone.now().timestamp(),
            'type': 'text',
            'msgid': message.uuid.hex
        }
        notification = Notification(
            sender=sender,
            receivers=chat.get_other_users(sender),
            type=Notification.TYPE_CHAT_MESSAGE,
            data=json.dumps(data)
        )
        notification.send()

但是当我调用 ChatNotifications.message_created(msg, chat) (消息和聊天已预先保存)时,我收到此错误:

ValueError: "<Notification: Notification object>" needs to have a value for field "notification" before this many-to-many relationship can be used.

在谷歌上搜索,我尝试做this,但这并没有解决我的问题。

通过调试,我检查了调用模型构造函数时抛出的错误。

这是踪迹:

Traceback (most recent call last):
File "<input>", line 1, in <module>
File "/home/vagrant/petycash/apps/chats/notifications.py", line 45, in message_created
data=json.dumps(data)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/base.py", line 550, in __init__
setattr(self, prop, kwargs[prop])
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 499, in __set__
manager = self.__get__(instance)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 476, in __get__
return self.related_manager_cls(instance)
File "/usr/local/lib/python3.5/dist-packages/django/db/models/fields/related_descriptors.py", line 783, in __init__
(instance, self.source_field_name))
ValueError: "<Notification: Notification object>" needs to have a value for field "notification" before this many-to-many relationship can be used.

【问题讨论】:

    标签: django python-3.x django-models


    【解决方案1】:

    Notification 保存之前,您不能将其与User 关联。

    所以你必须先保存Notification,然后你才能添加receivers

    notification = Notification(
        sender=sender,
        type=Notification.TYPE_CHAT_MESSAGE,
        data=json.dumps(data)
    ).save()
    # If chat.get_other_users(sender) return a queryset
    receivers = chat.get_other_users(sender)
    for receiver in receivers:
        notification.receivers.add(receiver)
    # or you can also simply assign the whole list as it's already empty after new create
    # >>> notification.receivers = recievers
    notification.send()
    

    【讨论】:

    • 这解决了这个问题,但现在,我得到 TypeError: 'ManyRelatedManager' object is not iterable。 get_other_users(user)方法的代码为:return self.users.exclude(pk=user.pk)
    • 如果 self.users.exclude(pk=user.pk) 返回一个用户列表,您可以遍历该列表并将每个用户添加到 notification 对象。 for user in chat.get_other_users(sender):notification.receivers.add(user)
    • exclude 返回一个查询集,如果我没记错的话,这是一个元组。
    • for other_user in chat.get_other_users(sender): notification.receivers.add(other_user) 出现同样的错误。
    • 对不起,这工作正常,当我访问发送方法时,问题是抛出。该线路是APNSDevice.objects.filter(user__in=self.receivers)。我使用APNSDevice.objects.filter(user__in=self.receivers.all()) 解决了它
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-08
    • 1970-01-01
    • 2017-06-01
    • 2017-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多