Darwin Tech
Darwin Tech

Reputation: 18929

Django adding a method to third party models

I have a Django project which uses a third party package that is installed via pip. I want to extend a model from that package and would like to know what the best practice is in this case. I can get the functionality I want by monkey patching, but I understand that this is not necessarily good practice. I am simply adding a method, so nothing which affects the database.

This is my current solution.

models.py:

from allauth.socialaccount.models import SocialAccount

def get_foo(self):
    ...
    return foo

SocialAccount.get_foo = get_foo

views.py

social_acc = SocialAccount.objects.get(
    ...
)

foo = social_acc.get_foo()

I feel I should be inheriting and sub-classing, but then of course I lose reference to the original model which contains all the basic data I need.

Upvotes: 2

Views: 1225

Answers (1)

Ludwik Trammer
Ludwik Trammer

Reputation: 25062

You definitely should use subclassing. If by "but then of course I lose reference to the original model which contains all the basic data I need" you mean that there will be a new database table created for your new subclass, there is a really simple solution for that. Use proxy inheritance:

from allauth.socialaccount.models import SocialAccount

class YourSocialAuth(SocialAccount):
    def get_foo(self):
        ...
        return foo

    class Meta:
        proxy = True

YourSocialAuth uses the same database table (including data it contains) as SocialAccount, so every object accessible through SocialAccount is also available through YourSocialAuth, but when you use the former, there is your custom method available:

social_acc = YourSocialAccount.objects.get(
    ...
)

foo = social_acc.get_foo()

Upvotes: 6

Related Questions