【问题标题】:Trying to use add_notification() method on UserProfile object, ValueError: cannot assign UserProfile - Notification.user must be a User instance尝试在 UserProfile 对象上使用 add_notification() 方法,ValueError: cannot assign UserProfile - Notification.user must be a User instance
【发布时间】:2021-03-26 07:58:25
【问题描述】:

我正在尝试在我的 django 应用程序中使用默认用户模型。我创建了UserProfile 对象来为用户提供自定义/附加字段。我正在尝试将 Notification 对象分配给每个 UserProfile,并且我有以下代码块

allUsers = User.objects.all()
for each in allUsers:
    uprof = UserProfile.objects.get_or_create(user=each)

for u in allUsers:
       if u.userprofile:
           notif1 = u.userprofile.add_notification(title="Welcome to our site " + u.email, body="Your first notification") # error
           notif2 = u.userprofile.add_notification(title="Sample Notification" + u.email, body="Empty template for " + u.email) # also same error

我在 django shell plus 中运行它。第一个 for 循环遍历所有用户并给他们一个 UserProfile 对象。第二个尝试使用名为add_notification() 的用户配置文件方法向该用户分配通知。这会失败并产生错误

ValueError: Cannot assign "<UserProfile: devtest4@gmail.com>": "Notification.user" must be a "User" instance.

我有点不知道这个错误信息是什么意思。即便如此,我认为这将是为每个现有用户分配用户配置文件然后向每个用户各自的用户配置文件添加通知的正确方法。我是不是搞错了?

user_profile/models.py

class UserProfile(models.Model):
    phone_number    = models.CharField(max_length=15, verbose_name='Phone Number')
    user            = models.OneToOneField(User, on_delete = models.CASCADE)
    api_key         = models.CharField(max_length=200, default='12345678')
    class Meta:
           verbose_name = "User Profile"
           verbose_name_plural = "User Profile"
    def __str__(self):
        return str(self.user.email)

    def add_notification(self, title, body):
        notif = Notification(user=self.user, title=title, body=body)
        notif.save()

通知/models.py

class Notification(models.Model):

    user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('receiver'), related_name='notifications_receiver')
    title = models.CharField(_('title'))
    body = models.TextField(_('text'), blank=True)
    timestamp = models.DateTimeField(_('timestamp'), auto_now_add=True)
    is_seen = models.BooleanField(_('seen status'), default=False)
    is_read = models.BooleanField(_('read status'), default=False)

【问题讨论】:

    标签: python django django-users


    【解决方案1】:

    正如您在错误中看到的那样:

    ValueError: Cannot assign "<UserProfile: devtest4@gmail.com>": "Notification.user" must be a "User" instance. 
    

    您正在尝试将 UserProfile 实例分配给此处应为 User 实例的字段:

    notif1 = u.userprofile.add_notification(title="Welcome to our site " + u.email, 
                                            body="Your first notification") 
    

    所以不要这样:

    for u in allUsers:
           if u.userprofile:
               notif1 = u.userprofile.add_notification(title="Welcome to our site " + u.email, 
                                                       body="Your first notification")
               notif2 = u.userprofile.add_notification(title="Sample Notification" + u.email, 
                                                      body="Empty template for " + u.email) 
    

    这样做:

    for u in allUsers:
           if u.userprofile:
               notif1 = u.userprofile.add_notification(user=u, 
                                                       title="Welcome to our site " + u.email, 
                                                       body="Your first notification")
               notif2 = u.userprofile.add_notification(user=u, 
                                                       title="Sample Notification" + u.email, 
                                                       body="Empty template for " + u.email)
    

    然后像这样重写你的方法:

    def add_notification(self, user, title, body):
        notif = Notification(user=user, title=title, body=body)
        notif.save()
    

    【讨论】:

    • 这似乎没有解决它,我仍然得到同样的错误。我认为我所写的内容和Notification.objects.create 之间的区别仅在于后者允许我避免调用.save()
    • 我使用的是默认用户模型from django.contrib.auth.models import User,抱歉我没有澄清。 UserProfile 对象有 user = models.OneToOneField(User, on_delete = models.CASCADE)Notification 对象有 user = models.ForeignKey(User, on_delete=models.CASCADE, verbose_name=_('receiver'), related_name='notifications_receiver')
    • 我更新了答案,抱歉回复太长了,我的灯灭了:)
    猜你喜欢
    • 2020-09-17
    • 2021-06-04
    • 2018-02-05
    • 1970-01-01
    • 2013-10-11
    • 2017-08-07
    • 1970-01-01
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多