AdminSite.get_app_list() doesn't seem to respect TransactionTestCase.available_apps

Hi,

When restricting the apps to be used in a test case (via TransactionTestCase.available_apps), the admin site still attempts to retrieve associated models in get_app_list() method and fails because the subsequent call to apps.get_app_config() returns the restricted version of available apps.

For further context, I encountered this issue while experimenting with Fixed #35380 -- Automated the screenshot generation process for docs. by nessita · Pull Request #18211 · django/django · GitHub where the news app is linked to the default admin. One way to reproduce this behavior is to duplicate news module with similar configuration and run the tests on both apps together. The index page shows 503 error page when running tests for the latter app.

I understand that the current test suite is organized such that each app has their own custom admin site instances. But if multiple apps would use the same admin site instance (default admin) the index would get broken.

Is this an expected behavior, or could it be a bug?

I’d say there’s no bug per se because available_apps is a private testing tool intended to help speed up certain tests. The fact that the admin method doesn’t work correctly when it’s used is not a huge surprise - changing apps feels like a hack that’s guaranteed to break something.

That said, we may be able to patch get_app_list() to restrict its results to apps currently registered. That seems reasonable to me, and maybe even desirable. Right now, it seems like it’s possible for real code to register a model with the admin while the app isn’t installed, which seems like a situation where something would go wrong.

I think the next step would be to try modifying AdminSite.get_app_list(), or probably its callee, _build_app_dict(), to see how easy it is to filter the results to installed apps only.

Hi @adamchainz

Right now, it seems like it’s possible for real code to register a model with the admin while the app isn’t installed, which seems like a situation where something would go wrong.

Do you have any specifc examples? I couldn’t find a way without dynamically changing available_apps which is for private testing as you said. Otherwise in most cases, I think Django doesn’t let importing models from not installed apps, let alone registering them to admin.

That said, we may be able to patch get_app_list() to restrict its results to apps currently registered.

On a related note if we go this route, should we restrict the models views too in get_urls()?

Overall I wouldn’t be too worried if disabling some INSTALLED_APPS and their app_configs is only allowed for internal testing.