The right place to keep my signals.py file in a Django project

前端 未结 8 878
天涯浪人
天涯浪人 2020-11-27 14:24

Based on Django\'s documentation I was reading, it seems like signals.py in the app folder is a good place to start with, but the problem I\'m facing is that wh

相关标签:
8条回答
  • 2020-11-27 14:29

    An alternative is to import the callback functions from signals.py and connect them in models.py:

    signals.py

    def pre_save_callback_function(sender, instance, **kwargs):
        # Do stuff here
    

    model.py

    # Your imports here
    from django.db.models.signals import pre_save
    from yourapp.signals import pre_save_callback_function
    
    class YourModel:
        # Model stuff here
    pre_save.connect(pre_save_callback_function, sender=YourModel)
    

    Ps: Importing YourModel in signals.py will create a recursion; use sender, instead.

    Ps2: Saving the instance again in the callback function will create a recursion. You can make a control argument in .save method to control it.

    0 讨论(0)
  • 2020-11-27 14:30

    I'm guessing that you're doing that so your signals are registered, so that they're found somewhere. I just put my signals right in a models.py file normally.

    0 讨论(0)
  • 2020-11-27 14:36

    I also put signals in signals.py file and also have this code snippet that loads all signals:

    # import this in url.py file !
    
    import logging
    
    from importlib import import_module
    
    from django.conf import settings
    
    logger = logging.getLogger(__name__)
    
    signal_modules = {}
    
    for app in settings.INSTALLED_APPS:
        signals_module = '%s.signals' % app
        try:
            logger.debug('loading "%s" ..' % signals_module)
            signal_modules[app] = import_module(signals_module)
        except ImportError as e:
            logger.warning(
                'failed to import "%s", reason: %s' % (signals_module, str(e)))
    

    This is for project, I'm not sure if it works at app level.

    0 讨论(0)
  • 2020-11-27 14:46

    In old Django versions would be fine to put the signals on the __init__.py or maybe in the models.py(although at the end models will be way to large for my taste).

    With Django 1.9, it is better I think, to place the signals on a signals.py file and import them with the apps.py, where they are going to be loaded after loading the model.

    apps.py:

    from django.apps import AppConfig
    
    
    class PollsConfig(AppConfig):
        name = 'polls'
    
        def ready(self):
            from . import signals  # NOQA
    

    You can also divide your signals on signals.py and handlers.py in another folder within your model named signals as well, but for me that is just over engineering. Take a look at Placing Signals

    0 讨论(0)
  • 2020-11-27 14:46

    This only applies if you have your signals in a separate signals.py file

    In completely agree with the answer of @EricMarcos but it should be stated that the django docs explicitly advice not to use the default_app_config variable (although it is not wrong). For current versions, correct way would be:

    my_app/apps.py

    from django.apps import AppConfig
    
    class MyAppConfig(AppConfig):
        name = 'my_app'
    
        def ready(self):
            import my_app.signals
    

    settings.py

    (Make sure you don't just have your app name in installed apps but instead the relative path to your AppConfig)

    INSTALLED_APPS = [
        'my_app.apps.MyAppConfig',
        # ...
    ]
    
    0 讨论(0)
  • 2020-11-27 14:50

    Original answer, for Django < 1.7:

    You can register the signals by importing signals.py in the app's __init__.py file:

    # __init__.py
    import signals
    

    This will allow to import models.py from signals.py without circular import errors.

    One problem with this approach is that it messes up the coverage results if you're using coverage.py.

    Related discussion

    Edit: For Django >= 1.7:

    Since AppConfig was introduced, the recommended way of importing signals is in its init() function. See Eric Marcos' answer for more details.

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