Comments (6)
Yes, this is on Master. When I get home I’ll try and get you a PR with a failing test case. Probably what I should have done first before blasting you with a wall of text.
from django-components.
OK, I think I've found the root cause. The class hash function here:
will return 2 different hashes if a class is imported using a different path.
Take for example, a Todo component with a .py file under components/todo/todo.py
. When using the regular @component.register("todo")
wrapper, the return value of cls.__module__
is todo
.
However, if you import the module in another file, such as urls.py
like this:
from components.todo.todo import TodoComponent
urlpatterns = [...]
the return value of cls.__module__
will be components.todo.todo
.
This is an issue because the documentation at
Line 449 in 91b4acc
urls.py
in the top level components
folder, and import the example competent like so:
from calendar import Calendar
However this import will not work if the urls.py module is in a directory above the calendar folder. You need to write it like this:
from components.calendar.calendar import Calendar
or use a relative import. Either way, the hash function will not match because the module will not simply be calendar
.
The only way to get this to work is if where you are importing the module (such as in a urls.py
) is in the same module as where the component is defined. And indeed, in the sample/test project that the component views tests use:
https://github.com/EmilStenstrom/django-components/blob/91b4accfebf74f3f7a8cf2ecab03789a1979d578/sampleproject/components/urls.py
the urls.py
file is in the same folder as greeting.py
where the component is actually defined. So in this case, the hash function will match - but this does not match what the documentation says to do.
So I think there are two options:
- Update the documentation to say that the
urls.py
file needs to be in the same directory as the module that defines the component, or - Make the hash function a bit more robust so that it stands up to imports from different paths.
EDIT:
I did some looking into this and I believe the root of this stems from the auto-detect and import that happens on init here:
No matter what I try, I cannot get the identity of the modules imported via autodetect to match the identity of classes imported later, such as in a urls.py
. The full module path does not match. This makes it hard to make the class_hash
method work.
As an example of this, I can make my project work by getting the component directly from the registry, thus circumventing the second attempt to register:
from django_components.component_registry import registry
urlpatterns = [path("components/todo", registry.get("todo").as_view(), name="todo")]
But this seems a little hacky.
Another option would be to make the class_hash
method a little less resrictive:
def class_hash(cls):
return hash(cls.__name__)
This will still prevent someone from the (probably most common case) of trying to register a second component under the same component name, unless the class name they use also matches, but at some point you gotta just stop it 🤷♂️
from django-components.
Hi @Fingel! Before going further into troubleshooting this: Are you sure you're using the latest version of the code? I JUST released 0.34 to pypi. Which version are you using? Does things work when you run the latest release?
from django-components.
@dylanjcastillo Is on it.
It was me who suggested this (faulty) change in the PR review, going with Dylan's original suggestions would have avoided this! :)
from django-components.
@Fingel, I got the PR for this now. Please give it a try, and let us know if it works!
@EmilStenstrom, no worries. I should've included a specific test for this, and we have that now!
from django-components.
Yes! It works now. Nice work. The python import system is so funky.
from django-components.
Related Issues (20)
- Bug: Context vars missing in slots when `isolated` settings
- "django_components.component" does not explicitly export attribute "register" HOT 10
- Async middleware HOT 5
- Tests refactor: Move from template files to inline templates HOT 2
- Define public API HOT 1
- template_loader blocks on STATICFILES_DIRS if there are tuples HOT 1
- Allow to render component dependencies without middleware HOT 24
- Feature parity with Juro's fork HOT 1
- Topic on new behaviour for dispatching slots using 'include' tags HOT 2
- Better support for AlpineJS HOT 5
- Scoped slots - Passing data to slots and accessing them in fills HOT 20
- Revert back to "django" as the default setting for "context_behavior"
- Refactor accessing of default slot from `as var` to kwarg HOT 3
- '
- Bug: Cannot override `block` tag inside `component` tag inside a template imported via `extends` in "django" mode HOT 2
- Support for dynamically loading component's JS/CSS dependencies HOT 2
- Typo Preventing html_attrs defaults from working HOT 2
- Inline tests/templates to make tests easier to follow HOT 1
- Allow to render a component, passing args and kwargs, from Python HOT 3
- Support for Paths as objects is missing HOT 25
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from django-components.