Alfred Huang
Alfred Huang

Reputation: 18235

Add class method after definition in a Python / Django model

I'm using Django, I import the User models by following:

from django.contrib.auth.models import User, Group, Permission

But now I want to add some class method to the User model class.

So here comes my general question: Can we add class method after the class was define?

for example:

class A:
    value = 123

def myfunc(self):
    return self.value

I want the myfunc to be member function of class A, how can it be? Plz help.

Upvotes: 1

Views: 2453

Answers (3)

Maxime Lorant
Maxime Lorant

Reputation: 36141

Since you are talking about the Django User model, you should create your own model, extending the User. To do this, you just need to create a model with a OneToOne relation with the User model:, you should create a new User model, by extending AbstractUser:

from django.contrib.auth.models import AbstractUser

class MyUserModel(AbstractUser):
    # AbstractUser has already every fields needed: username, password, is_active...
    def myfunc(self):
        # Just a dummy working example
        return "My Username in uppercase: %s" % self.username.upper()

And put AUTH_USER_MODEL = "yourapp.MyUserModel" in settings.py

Then, you can use this new user model as if it was the User: it has the same methods than User (like create_user, check_password...), and you can access to myfunc with user.myfunc(), where user is the regular MyUserModel instance (get from request.user or the ORM). This is more consistent with the framework organisation and allow you to add more fields to the User if you want.


Side-note: As @Daniel Roseman pointed out in comments, you should really extend the AbstractUser model now (since Django 1.6) instead of make an UserProfile "proxy".

Related questions:

Upvotes: 1

jtiai
jtiai

Reputation: 611

Profile is just fine, it will work and there is no problem with that. One option that is actually meant in Django ORM is proxy models. In proxied model you can have all the fields of parent model and add your custom methods or managers without changing parent model.

from django.contrib.auth.models import User

class MyUser(User):
    class Meta:
        proxy = True


    def my_method(self):
        return self.name

Upvotes: 0

Germano
Germano

Reputation: 2482

You can add a class method by assignment, as user2357112 suggested.

class A(object):
    value = 123

def myfunc(cls):
    return cls.value

A.myfunc = classmethod(myfunc)

print A.myfunc()
> 123

As for Django models, you probably might want to use a custom Manager to handle functionality for all users instead of class methods. But I can't say more without further information.

Upvotes: 0

Related Questions