Question

I want to be able to be able to run a function from my model "ModelLog" in the following way:

ModelLog.create_log(user, obj1, obj2)

instead of creating first and empty object to pass along with it. Now i figured out this could be done by rewriting the init But to be fair, this is all new to me.

my class ModelLog has this method:

class ModelLog(models.Model):

    def create_log(user_obj, old_obj, new_obj):
        """ Create a log about the changes of an object"""

        "Some Code"

When i use ModelLog.create_log(user, obj1, obj2) to execute my create_log method i get the following error:

TypeError: unbound method create_log() must be called with ModelLog instance as first argument (got User instance instead)

now i thought i needed to do something like:

def __init__(self, user_obj, old_obj, new_obj):
    self.user_obj = user_obj
    self.old_obj = old_obj
    self.new_obj = new_obj

But clearly, this isnt working, can someone please put me in the right direction and help me out here?

Was it helpful?

Solution

The problem is you are calling a method like a class method. When you define a method in python you need to add an extra parameter which represent the object instance for the calling or (like your case) the class.

So you should rewrite your code:

def create_log(cls, user_obj, old_obj, new_obj):
    """ Create a log about the changes of an object"""

Or in a more pythonic way:

@classmethod
def create_log(cls, user_obj, old_obj, new_obj):
    """ Create a log about the changes of an object"""

Or in case you want a static method:

@staticmethod
def create_log(user_obj, old_obj, new_obj):
    """ Create a log about the changes of an object"""

If you are interested(confused) I recommend you to read this.

OTHER TIPS

If you want to be able to call create_log as a static method (one that isn't linked to a single object) you'll need to use the static method decorator

Try doing something like

class ModelLog(models.Model):

    @staticmethod
    def create_log(user_obj, old_obj, new_obj):
        """ Create a log about the changes of an object"""

        pass #Create your object here

You probably don't need to customise your __init__ method for this usecase, just forget about that for now.

As for your error, you need to provide a dummy first argument to create_log and declare it a @classmethod:

class ModelLog:

  @classmethod
  def create_log(self, user_obj, old_obj, new_obj):
    ...

Note the extra self.

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