Opened 3 months ago

Last modified 3 months ago

#36424 assigned Cleanup/optimization

Extend documentation related to handling of model name collisions in shell auto-imports

Reported by: john-parton Owned by: SOHAIL AHMAD
Component: Core (Management commands) Version: 5.2
Severity: Normal Keywords:
Cc: Salvo Polizzi, Adam Johnson, Bhuvnesh Triage Stage: Accepted
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: yes
Easy pickings: no UI/UX: no

Description

If you have two models with the same name, the automatic import logic will result in just one of them being imported.

$ ./manage.py shell -v2
116 objects imported automatically:

  from apps.order.models import Line, Order
  from apps.cart.models import Line, Cart

Python 3.13.3 (main, Apr  9 2025, 04:03:52) [Clang 20.1.0 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> Line
<class 'apps.cart.models.Line'>

shell_plus has a few different ways to resolve this issue: https://django-extensions.readthedocs.io/en/latest/shell_plus.html#configuration

In my settings.py, I have the following

SHELL_PLUS_MODEL_ALIASES = {
    "cart": {"Line": "CartLine"},
    "order": {"Line": "OrderLine"},
}

To make matters even more annoying, if you have isort installed, the verbose output doesn't even match the expected behavior of the last import being the ultimately imported symbol.

Output with isort

$ ./manage.py shell -v2
116 objects imported automatically:

  from apps.cart.models import Cart, Line
  from apps.order.models import Line, Order

Python 3.13.3 (main, Apr  9 2025, 04:03:52) [Clang 20.1.0 ] on linux
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> Line
<class 'apps.cart.models.Line'>

Note that you do not get a warning even if you run python with -Wall

I'm inclined to say that the behavior as-is could be considered a bug. From the perspective of the user, there's no explicable reason why one model is picked over the other and there's no indication that such an overwrite took place. However, this is basically the same behavior as shell_plus, so perhaps that's being too harsh with django.

Some possible fixes:

  1. Document the behavior, maybe here: https://docs.djangoproject.com/en/5.2/howto/custom-shell/ ; and/or
  2. Emit a warning in this case; and/or
  3. Don't import either model

Alternatively, implement user configurable "import as" or aliases, although that's outside the scope of a bugfix and into feature territory.

Change History (6)

comment:1 by Clifford Gama, 3 months ago

Thanks for taking the time to create this ticket.

I can reproduce this, but for me this is expected behavior, as documented here:

Models from apps listed earlier in INSTALLED_APPS take precedence.

That said, the note could benefit from improved wording to make the meaning more explicit. E.g.

If multiple apps define models with the same name, the model from the app listed earlier in INSTALLED_APPS will overwrite any previously imported model of the same name.

isort's role isn't documented and can easily confuse users trying to understand why one model was imported over another. I think we should add a note in the documentation and/or shell command help that the order shown may be affected by isort and may not the order actually used?

Leaving it unreviewed for now so others can weigh in on whether a warning or automatic resolution for name conflicts is worth pursuing.

comment:2 by Clifford Gama, 3 months ago

Summary: Identically named models in different appsImprove handling of model name collisions in shell auto-imports

comment:3 by Natalia Bidart, 3 months ago

Cc: Salvo Polizzi Adam Johnson Bhuvnesh added
Summary: Improve handling of model name collisions in shell auto-importsExtend documentation related to handling of model name collisions in shell auto-imports
Triage Stage: UnreviewedAccepted
Type: BugCleanup/optimization

Thank you John for your ticket, and thank you Clifford for the initial triage.

As Clifford says, this is documented and it was discussed at length in the forum post about this feature, and in the PR. This "priority" order also matches what is done in any other place where collisions can happen (management commands themselves, templates, translations, etc).

Documentation improvements are always welcome! We can accept the ticket on that basis. I would be open to consider a warning being shown, though that would have to be a 6.0-only feature due to the current translations string freeze that we have in effect for 5.2.

comment:4 by john-parton, 3 months ago

I'll see if I can improve the documentation slightly. My reading comprehension isn't the best, but I didn't realize that sentence was referring to this behavior.

Regarding warnings, I mostly meant a warning emitted if Python is run with -Wall. I don't believe those messages are internationalized, so my understanding is that it could be merged in before 6.0. Is that correct or am I mistaken?

(Aside: I'm of the opinion that if a user has to search the forums to figure something out, it's a sign that docs could be better.)

comment:5 by SOHAIL AHMAD, 3 months ago

Owner: set to SOHAIL AHMAD
Status: newassigned

comment:6 by Clifford Gama, 3 months ago

Has patch: set
Patch needs improvement: set
Note: See TracTickets for help on using tickets.
Back to Top