Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create user notification system in Django

I am adding a system to leave "notifications" for users that can be displayed the next time they log in. I created a simple Notification class in the models.py file. I have this UserInfo class (in the same models.py) to add on some attributes to Django's existing user system as part of socialauth:

class UserInfo(models.Model):
    user = models.OneToOneField(User, unique=True)
    ...
    reputation = models.IntegerField(null=True, blank=True)

    def add_notification(message):
        notification = Notification(user=self.user, message=message)
        notification.save

When I try it out in the console I end up with this:

>>> user = User.objects.get(id=14)
>>> user.userinfo.add_notification('you are an awesome intern!')
Traceback (most recent call last):
  File "<console>", line 1, in <module>
TypeError: add_notification() takes exactly 1 argument (2 given)
>>> 

What am I missing here? I'm kind of a Django noob so maybe it's something easy. Thanks!

like image 406
gohnjanotis Avatar asked Nov 19 '10 20:11

gohnjanotis


1 Answers

Use Django messages

First off, please consider dcrodjer's answer. The Django message system is exactly what you need, and why put in your code tree something that you get for free?

(Of course, if you're doing this just to experiment and learn more about Django, please continue!)


Anyway, a fix

Summary: To fix this, just change add_notifications to this:

    def add_notification(self, message):
        notification = Notification(user=self.user, message=message)
        notification.save

Note the additional argument (named self) in the method signature.


Why it's not working

There's a bit of a quirk in calling methods in Python.

class Foo(object):
    def bar(self):
        print 'Calling bar'

    def baz(self, shrubbery):
        print 'Calling baz'

thisguy = Foo()

When you call the method bar, you can use a line like thisguy.bar(). Python sees that you're calling a method on an object (a method called bar on an object called thisguy). When this happens, Python fills in the first argument of the method with the object itself (the thisguy object).

The reason your method doesn't work is that you are calling userinfo.add_notification('you are an awesome intern!') on a method that is only expecting one argument. Well, Python has already filled in the first argument (named message) with the userinfo object. Thus, Python complains that you're passing two arguments to a method that only expects one.

like image 166
Wesley Avatar answered Oct 20 '22 18:10

Wesley