I'm trying to use the default user model in my django application. I created UserProfile
objects to have custom/additional fields for users. I'm trying to assign Notification objects to each UserProfile and I have the following code block
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
I was running this in a django shell plus. The first for loop iterates through all users and gives them a UserProfile object. The second tries to assign a notification to that user with a userprofile method called add_notification()
. This fails and generates the error
ValueError: Cannot assign "<UserProfile: devtest4@gmail.com>": "Notification.user" must be a "User" instance.
I kinda don't really know what this error message means. And even so, I thought this would be the correct way of assigning a UserProfile to every existing User and then adding a notification to each user's respective userprofile. Am I going about this wrong?
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()
notifications/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)
As you can see in your error:
ValueError: Cannot assign "<UserProfile: devtest4@gmail.com>": "Notification.user" must be a "User" instance.
you are trying to assign a UserProfile instance to a field that should be a User instance here:
notif1 = u.userprofile.add_notification(title="Welcome to our site " + u.email,
body="Your first notification")
so instead of this:
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)
do this:
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)
and rewrite your method like this:
def add_notification(self, user, title, body):
notif = Notification(user=user, title=title, body=body)
notif.save()