Open
Conversation
Configure Django during `from nanodjango import Django` instead of waiting
for `app = Django()`. This enables PEP8-compliant import ordering and
module-level settings.
Key changes:
- Add early.py for AST-based settings extraction and early Django setup
- Use lazy loading via __getattr__ to support both direct and CLI modes
- Extract simple settings early, apply complex settings at Django() time
- Update commands.py to defer Django import for CLI compatibility
- Add MIGRATION_MODULES to early config
This allows patterns like:
from nanodjango import Django
from django.contrib.auth.models import User # Now works!
And module-level settings:
DEBUG = False
if os.environ.get("PROD"):
ALLOWED_HOSTS = ["example.com"]
Closes radiac#34, radiac#43, radiac#85
- Skip injected settings when collecting unused definitions - Update requires-python to >=3.10 (Django 5.2 requirement) - Add test dependencies to pyproject.toml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR implements early Django configuration, addressing several long-standing issues around import order and PEP8 compliance (#34, #43, #85).
The Problem
Previously, Django wasn't configured until
app = Django()was called. This meant:from django.contrib.auth.models import User) had to come afterapp = Django()deferto work around import order issuesThe Solution
Django is now configured during
from nanodjango import Djangovia a two-phase approach:Phase 1: Early extraction (AST parsing)
from nanodjango import Django, the source file is parsed via ASTPhase 2: Late update (at Django() instantiation)
app = Django()is called, the module has fully executedWhat This Enables
Key Implementation Details
Lazy loading via
__getattr__(__init__.py)Djangoclass is only imported when first accessedNew
early.pymoduleEarlyConfiguratorclass handles AST parsing and Django setupBASE_DIR,Path, andosinto the evaluation contextCLI mode support (
commands.py)python script.pyandnanodjango run script.pyLate settings update (
app.py)deferis now rarely neededWith early configuration working in all modes,
nanodjango.deferis now only needed for unusual third-party packages that perform initialization at import time in ways that conflict with early configuration.Test plan
python script.py) works with User importnanodjango run script.py) works with User importDocumentation
Updated:
docs/settings.rst- New module-level settings section with "How it works" explanationdocs/defer.rst- Note that defer is rarely needed nowdocs/tutorial.rst- Updated model definition guidancedocs/troubleshooting.rst- Updated "Settings not configured" sectiondocs/changelog.rst- Added 0.14.0 entryCloses #34, #43, #85