Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

@classmethod not working #81

Open
fletom opened this Issue · 5 comments

2 participants

Fletcher Tomalty namlook
Fletcher Tomalty

I have the following code, with a class method.

@connection.register
class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    @classmethod
    def create_or_update_by_id(cls, id, screen_name, token, secret):
        print (cls, cls())
        user = cls.find_one({'id': id}) or cls()

        user.id = id
        user.screen_name = screen_name
        user.token = token
        user.secret = secret

        user.validate()

        return user

But when I call it, with db.User.create_or_update_by_id(...) I get the following error:

TypeError: unbound method find_one() must be called with CallableUser instance as first argument (got mongo_query instance instead)

In other ORMs this works. Do class methods not work in MongoKit, or am I doing something wrong?

Fletcher Tomalty fletom closed this
Fletcher Tomalty fletom reopened this
namlook
Owner

By design, all Documents accessed via db (db.Document.find()) are already instanciated. So you don't need to call @classmethod. Your User class would look like :

class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    def create_or_update_by_id(self, id, screen_name, token, secret):
        self.id = id
        self.screen_name = screen_name
        self.token = token
        self.secret = secret
        self.validate() # why not saving here ?
        return self
namlook namlook closed this
Fletcher Tomalty

No, that doesn't work. The whole point is to create it only if the ID doesn't already exist. That's what the cls.find_one({'id': id}) or cls() line is for. If the find_one returns None, it creates a new User object by calling cls.

namlook
Owner

Well, in this case:

class User(Document):
    __collection__ = 'users'
    structure = {
        'id': int,
        'screen_name': unicode,
        'token': unicode,
        'secret': unicode,
    }

    use_dot_notation = True

    def create_or_update_by_id(self, id, screen_name, token, secret):
        user = self.db.User.find_one({'_id': id}) or self.db.User()
        user.id = id
        user.screen_name = screen_name
        user.token = token
        user.secret = secret
        user.validate() # why not saving here ?
        return user
Fletcher Tomalty

That doesn't make any sense. Why would User have to specify itself in its methods? Or the db for that matter? And this is totally weird because self is an instance of User and you're using it to create new User objects. Completely un-Pythonic. Why don't class methods work? They are the only elegant solution.

namlook
Owner

Yes, I know this is weird and completely un-Pythonic but this design inherits from a (very old) historical design. I tried to refactorise but the bad was already done (ie too many people were using MongoKit) and I don't have time anymore to fix this.

If you want you can provide a patch to fix this issue.

I re-open this ticket.

namlook namlook reopened this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.