Closed danjac closed 1 month ago
@danjac What happens if you just remove all settings? The way you've set things up is the default, so you shouldn't need any settings, either app_dirs, dirs, or libraries.
We shouldn't break like that, so just trying to find a workaround.
I get the same error with the COMPONENTS
setting commented out.
@danjac Could you create a demo project? I wasn't able to reproduce this.
My guess is that it has to do with this import path:
.venv.lib.python3.12.site-packages.django_components.components.__init__
It's the path to django_components.components
, and it's there because we also look for 3rd party installed Django apps that are installed (django_components
), and search for app_dirs
in them (so django_components.components
).
Then there's one safeguard to ignore those paths that are outside of the project root.
Could be that you have BASE_DIR
set one level higher. When I implemented this I assumed that BASE_DIR
would be the root, so any path below it would be one of Django apps. Your Django apps are one level deeper, in [BASE_DIR / "django_project"
. So you would have to set the root to [BASE_DIR / "django_project"
. Then the path to .venv
is not inside of the project root anymore, and so we would NOT try to load it.
But the whole problem with this import is that we try to import from .venv
. The way we obtain the path is that we use Django's AppConfig.path
which is a filesystem path (with forward slashes), e.g.
./.venv/lib/python3.12/site-packages/django_components/components
And we convert it to a module path (with dots), e.g.
.venv.lib.python3.12.site-packages.django_components.components
And so then we get a module path that starts with a dot, which causes the error.
So I see now that the strategy to ignore paths outside of the root project is not sufficient. And we need a way to be able to handle third party packages. Don't know if we can get that info from the AppConfig instance. What we can do alternatively is that if the app path includes site-packages
, then we drop the path leading up to it (inclusive).
So
.venv.lib.python3.12.site-packages.django_components.components
Would become
django_components.components
Right - for the record, I'm using pdm, which has the default behavior of creating a .venv
virtualenv directory in the project root - other packaging systems e.g. Poetry or uv do something similar, so this is a very common scenario.
Second, you're correct that my BASE_DIR
is the top level, under which I have my django_project
and under django_project
I have individual apps. Again, this is a common pattern and normally works fine.
I'm not aware of how your autodiscover is implemented, but looking at prior art we have template tags: I can add templatetags
packages under each app, and I can specify specific modules under OPTIONS.builtins
in the TEMPLATES
directory, and Django is able to find all of these provided they are available to the PYTHONPATH, so I was assuming django-components does the same?
For reference: how template tag lookups are done in Django: https://github.com/django/django/blob/main/django/template/backends/django.py
@danjac Thanks for linking Django's code. So they use AppConfig.name
as the import path.
The relevant part is line 140:
f"{app_config.name}.templatetags" for app_config in apps.get_app_configs()
I had the same idea this morning. Though ChatGPT suggested that technically the AppConfig.name
doesn't necessarily have to match the import path for given app.
But seeing that Django themselves use AppConfig.name
like this, then IMO we can do the same :)
Btw, @danjac, does it then mean that your my_app
app from your example earlier has apps.py
like this?
class MyAppConfig(AppConfig):
name = "django_project.my_app"
...
That is, that the name is django_project.my_app
?
Yes that's correct, something like
class MyAppConfig(AppConfig):
name = "django_project.my_app"
This has now been fixed in https://github.com/EmilStenstrom/django-components/releases/tag/0.101 🎉
Works great, thank you!
This error happens at startup:
Settings:
Previous (working) 0.97 settings:
i.e. I have a number of components defined in modules under
django_project/components
e.g.django_project/components/buttons.py
and app-specific components underdjango_project/my_app/components
e.g.django_project/my_app/components/cards.py
.Using Python 3.12.