Question

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!

Was it helpful?

Solution

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.

OTHER TIPS

Use the django message framework: http://docs.djangoproject.com/en/dev/ref/contrib/messages/
You may put the userinfo stored messages in queue as soon as he logs in using this:

messages.add_message(request, messages.INFO, 'Hello world.')

add_notification is a method on a class. That means it implicitly gets passed the instance of the class as the first parameter. Classes in Python

Try this instead:

class UserInfo(models.Model):
    ...
    def add_notification(self, message):
        ...

You should perhaps update your question if you're looking for persistent messaging. Maybe https://github.com/philomat/django-persistent-messages can help you save coding time?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top