System Crashes on Load if Async Not Configured
Oops. I configured a small downstream project with powercrud without requiring ASYNC_ENABLED (actually without even settings.POWERCRUD_SETTINGS which is an bigger fail gievn it didn't report that was the issue). The system crashed on load because it tries to load django_q and requires settings.Q_CLUSTER even when not required.
We need to put some guards in to m ake the system robust. I got too caught up in my current dev environment with a very sophisticated setup for powercrud and forgot about the basic use cases. Oops.
Summary
PowerCRUD currently assumes the async stack (django-q + Q_CLUSTER) exists the moment powercrud.mixins is imported. PowerCRUDMixin inherits AsyncMixin, which imports AsyncManager, which immediately imports django_q objects and touches settings.Q_CLUSTER. On lightweight installs (like the nanodjango demo) there is no POWERCRUD_SETTINGS, no django_q in INSTALLED_APPS, and no Q_CLUSTER, so simple imports crash before Django even configures settings. Downstream apps cannot opt out because the import happens at module load, not when async is explicitly enabled. We also need to confirm whether POWERCRUD_SETTINGS itself is optional: the guard logic should treat the setting as optional unless a project explicitly enables async, but we currently blow up even when the dict is absent.
Diagnostics so far:
AsyncManagerperforms eager imports (from django_q.models import Task, etc.) and accessessettings.Q_CLUSTERin__init__, so import order alone can trigger ImproperlyConfigured.AsyncMixin.get_bulk_async_enabled()only checks per-view flags; it never verifies that async is globally enabled or that django-q exists, so the guardrail is ineffective.- Tests only run under the “full” settings module where django-q is installed, so we never exercised the “no async” scenario in CI.
The fix needs to keep async optional: PowerCRUD should import cleanly without django-q, and async behaviour should only activate when both POWERCRUD_SETTINGS["ASYNC_ENABLED"] and django-q are configured. Architecturally, that means treating async as an explicit add-on: the default PowerCRUDMixin should stay synchronous and lightweight, while async capabilities are layered on via AsyncMixin (and a convenience composite mixin) in projects that intentionally opt into django-q.
Issues to Address
- Eager imports in
powercrud.async_managerandpowercrud.async_hooks. AsyncMixinfalls back tobulk_async=Falsebut still imports the async stack during module load.- No regression tests guarantee a basic project (no
POWERCRUD_SETTINGS, no django-q) can importPowerCRUDMixin. - Test suite only runs with the rich async settings module; we need a minimal settings file (no django_q, no POWERCRUD_SETTINGS) plus pytest hooks so core tests run there without exploding.
- Documentation doesn’t mention that django-q is optional/guarded—users assume it is required.
Phased Plan
NOTE: Phase 2 is more "nice to have" than critical.
- Decouple async from the default mixin and add minimal test coverage.
1.1. [X] Remove
AsyncMixinfromPowerCRUDMixinand introduce aPowerCRUDAsyncMixin(or similar) that composesAsyncMixinandPowerCRUDMixinfor downstream convenience. 1.2. [X] Update any tests that relied on async being present in the defaultPowerCRUDMixin(e.g. views that implicitly exercised async behaviour) so they explicitly include the async mixin/composite. 1.3. [X] Create a minimal test settings module withoutPOWERCRUD_SETTINGSand withoutdjango_qinINSTALLED_APPS; add smoke tests under that module to prove imports/CRUD views still work in a “no async” configuration. 1.4. [X] Ensure async-only tests usepytest.importorskip("django_q")(or equivalent) so running the core suite under the minimal settings does not explode. 1.5. [X] Introduce clearerImproperlyConfiguredmessages where appropriate (e.g. missingPOWERCRUD_SETTINGSwhen async is explicitly enabled, or async mixins/managers used without django-q/Q_CLUSTER) and document the breaking change in the changelog/release notes. 1.6 [X] update docs appropriately to reflect new approach for async - Harden async guards and error paths inside the async modules.
2.1. [ ] Move
django_qimports inside a helper that caches the modules and raises a friendly error when async is used without django-q. 2.2. [ ] Delay readingsettings.Q_CLUSTERuntil async is explicitly enabled and Django settings are configured, and ensure calls made too early produce a targeted configuration error rather than a low-level traceback. 2.3. [ ] UpdateAsyncMixinandAsyncManagerto short-circuit gracefully when async is disabled globally or dependencies are missing, with log messages that make it obvious why async is inactive. 2.4. [ ] Expand tests for misconfigured async (wrong/missingPOWERCRUD_SETTINGS, partial django-q setup) so we get clean, localised failures instead of crashes from deep inside django-q. 2.5. [ ] Update async guide + README to clarify the “sync by default, async opt-in” model, document how to run the minimal-settings test suite, and add a release-note entry describing the guard and test coverage improvements.