How To Run Arbitrary Code After Django is “Fully Loaded”

前端 未结 4 1529
失恋的感觉
失恋的感觉 2020-12-17 09:46

I need to perform some fairly simple tasks after my Django environment has been \"fully loaded\".

More specifically I need to do things like Signal.disconnect(

相关标签:
4条回答
  • 2020-12-17 10:32

    I had to do the following monkey patching. I use django 1.5 from github branch. I don't know if that's the proper way to do it, but it works for me.

    I couldn't use middleware, because i also wanted the manage.py scripts to be affected.

    anyway, here's this rather simple patch:

    import django
    from django.db.models.loading import AppCache
    
    django_apps_loaded = django.dispatch.Signal()
    
    def populate_with_signal(cls):
        ret = cls._populate_orig()
        if cls.app_cache_ready():
            if not hasattr(cls, '__signal_sent'):
                cls.__signal_sent = True
                django_apps_loaded.send(sender=None)
        return ret
    
    if not hasattr(AppCache, '_populate_orig'):
        AppCache._populate_orig = AppCache._populate
        AppCache._populate = populate_with_signal
    

    and then you could use this signal like any other:

    def django_apps_loaded_receiver(sender, *args, **kwargs):
        # put your code here.
    django_apps_loaded.connect(django_apps_loaded_receiver)
    
    0 讨论(0)
  • 2020-12-17 10:35

    My question is a more poorly phrased duplicate of this question: Where To Put Django Startup Code. The answer comes from that question:

    Write middleware that does this in init and afterwards raise django.core.exceptions.MiddlewareNotUsed from the init, django will remove it for all requests...

    See the Django documentation on writing your own middleware.

    0 讨论(0)
  • 2020-12-17 10:40

    In Django 1.7 Apps can implement the ready() method: https://docs.djangoproject.com/en/dev/ref/applications/#django.apps.AppConfig.ready

    0 讨论(0)
  • 2020-12-17 10:45

    As far as I know there's no such thing as "fully loaded". Plenty of Django functions include import something right in the function. Those imports will only happen if you actually invoke that function. The only way to do what you want would be to explicitly import the things you want to patch (which you should be able to do anywhere) and then patch them. Thereafter any other imports will re-use them.

    0 讨论(0)
提交回复
热议问题