How to monkey patch Django?

Viewed 14885

I came upon this post on monkey patching Django:

from django.contrib.auth.models import User

User.add_to_class('openid', models.CharField(max_length=250,blank=True))

def get_user_name(self):
    if self.first_name or self.last_name:
        return self.first_name + " " + self.last_name
    return self.username

User.add_to_class("get_user_name",get_user_name)

I understand that this isn't ideal and it's better to add fields and functions to User through a separate model Profile.

With that said, I just want to understand how this would work:

  1. Where would I put the monkey patching code?

  2. When is the code run -- just once? once per Python interpreter startup? once per request?

  3. Presumably I'd still need to change the DB schema. So if I dropped the table User and ran ./manage.py syncdb, would syncdb "know" that a new field has been added to User? If not how do I change the schema?

3 Answers

Using both @suhailvs and @Paul McMillan's suggestions I added a patch.py file to the root of my app, and inside the app's apps.py called my patched in the ready signal:

from django.apps import AppConfig

class MyAppConfig(AppConfig):
    name = "MyApp"

    def ready(self):
        """
        Called when the app is ready.
        """
        from .patch import patch_func

        patch_func()

The AppRegistryNotReady: Apps aren't loaded yet. happens because of the import, not the function call, so it must be inside the function.

Related