[Django]-How to fix circular importing?

3πŸ‘

βœ…

You can import modules locally in the body of the function, so:

from lumis.utils import get_random_string


def unique_order_reference_generator():
    from .models import Order, ReservedItem

    new_id = get_random_string(length=10)

    reserved_item = ReservedItem.objects.filter(
        order_reference=new_id
    ).exists()
    order = Order.objects.filter(order_reference=new_id).exists()

    if reserved_item or order:
        return unique_order_reference_generator()
    else:
        return new_id

This thus means that the module is not loaded when Python loads the file, but when the function is actually called. As a result, we can load the unique_order_reference_generator function, without having to load a the module that actually depends on this function.

Note that, like @Alasdair says, signals are typically defined in a dedicated file (signals.py) for example which should be loaded in the ready() function of the app. But regardless how you structure code, frequently local imports should be used to avoid circular imports.

2πŸ‘

All the current suggestions are good. Move your signal handlers out of models. Models are prone to circular imports because they are used everywhere, so it is a good idea to keep only model code in models.py.

Personally, I don’t like imports in the middle of the code

import-outside-toplevel / Import outside toplevel

Instead I use Django application API to load models without importing

from django.apps import apps

def signal_handler(instance, *args, **kwargs):
    Order = apps.get_model('your_app', 'Order')
    ...
πŸ‘€Mad Wombat

Leave a comment