From 3fe0491da8c9f34cb2ae8ef115f8df47ce77708a Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 04:09:36 -0700
Subject: [PATCH 1/8] use snake_case component names
---
README.md | 8 ++---
docs/features/components.md | 12 +++----
docs/features/hooks.md | 8 ++---
docs/features/templatetag.md | 16 +++++----
src/django_idom/templatetags/idom.py | 2 +-
tests/test_app/components.py | 36 +++++++++----------
...tatic-css-test.css => django-css-test.css} | 2 +-
tests/test_app/static/django-js-test.js | 3 ++
tests/test_app/static/static-js-test.js | 3 --
tests/test_app/templates/base.html | 18 +++++-----
tests/test_app/tests/test_components.py | 4 +--
11 files changed, 57 insertions(+), 55 deletions(-)
rename tests/test_app/static/{static-css-test.css => django-css-test.css} (61%)
create mode 100644 tests/test_app/static/django-js-test.js
delete mode 100644 tests/test_app/static/static-js-test.js
diff --git a/README.md b/README.md
index 58f86611..dfee8134 100644
--- a/README.md
+++ b/README.md
@@ -25,7 +25,7 @@ Any Python web framework with Websockets can support IDOM. See below for what fr
-You'll need a file to define your [IDOM](https://github.com/idom-team/idom) components. We recommend creating a `components.py` file within your chosen **Django app** to start out. Within this file, we will create a simple `HelloWorld` component.
+You'll need a file to define your [IDOM](https://github.com/idom-team/idom) components. We recommend creating a `components.py` file within your chosen **Django app** to start out. Within this file, we will create a simple `hello_world` component.
@@ -34,7 +34,7 @@ You'll need a file to define your [IDOM](https://github.com/idom-team/idom) comp
from idom import component, html
@component
-def HelloWorld(recipient: str):
+def hello_world(recipient: str):
return html.h1(f"Hello {recipient}!")
```
@@ -46,7 +46,7 @@ def HelloWorld(recipient: str):
In your **Django app**'s HTML template, you can now embed your IDOM component using the `component` template tag. Within this tag, you will need to type in your dotted path to the component function as the first argument.
-Additonally, you can pass in keyword arguments into your component function. For example, after reading the code below, pay attention to how the function definition for `HelloWorld` (_in the previous example_) accepts a `recipient` argument.
+Additonally, you can pass in keyword arguments into your component function. For example, after reading the code below, pay attention to how the function definition for `hello_world` (_in the previous example_) accepts a `recipient` argument.
@@ -56,7 +56,7 @@ Additonally, you can pass in keyword arguments into your component function. For
- {% component "example_project.my_app.components.HelloWorld" recipient="World" %}
+ {% component "example_project.my_app.components.hello_world" recipient="World" %}
```
diff --git a/docs/features/components.md b/docs/features/components.md
index 947a4431..dc697162 100644
--- a/docs/features/components.md
+++ b/docs/features/components.md
@@ -7,7 +7,7 @@ from idom import component, html
from django_idom.components import django_css
@component
-def MyComponent():
+def my_component():
return html.div(
django_css("css/buttons.css"),
html.button("My Button!"),
@@ -29,7 +29,7 @@ def MyComponent():
from django.templatetags.static import static
@component
- def MyComponent():
+ def my_component():
return html.div(
html.link({"rel": "stylesheet", "href": static("css/buttons.css")}),
html.button("My Button!"),
@@ -46,7 +46,7 @@ def MyComponent():
from idom import component, html
@component
- def MyComponent():
+ def my_component():
return html.div(
html.link({"rel": "stylesheet", "href": "https://example.com/external-styles.css"}),
html.button("My Button!"),
@@ -68,7 +68,7 @@ from idom import component, html
from django_idom.components import django_js
@component
-def MyComponent():
+def my_component():
return html.div(
html.button("My Button!"),
django_js("js/scripts.js"),
@@ -90,7 +90,7 @@ def MyComponent():
from django.templatetags.static import static
@component
- def MyComponent():
+ def my_component():
return html.div(
html.script({"src": static("js/scripts.js")}),
html.button("My Button!"),
@@ -107,7 +107,7 @@ def MyComponent():
from idom import component, html
@component
- def MyComponent():
+ def my_component():
return html.div(
html.script({"src": static("https://example.com/external-scripts.js")}),
html.button("My Button!"),
diff --git a/docs/features/hooks.md b/docs/features/hooks.md
index e1cc4d04..b253e26f 100644
--- a/docs/features/hooks.md
+++ b/docs/features/hooks.md
@@ -13,7 +13,7 @@ from idom import component, html
from django_idom.hooks import use_websocket
@component
-def MyComponent():
+def my_component():
my_websocket = use_websocket()
return html.div(my_websocket)
```
@@ -29,7 +29,7 @@ from idom import component, html
from django_idom.hooks import use_scope
@component
-def MyComponent():
+def my_component():
my_scope = use_scope()
return html.div(my_scope)
```
@@ -39,7 +39,7 @@ def MyComponent():
??? info "This hook's behavior will be changed in a future update"
- This hook will be updated to return the browser's current URL. This will come in alongside our built-in [Single Page Application (SPA) support](https://github.com/idom-team/idom/issues/569).
+ This hook will be updated to return the browser's current URL. This change will come in alongside [IDOM URL routing support](https://github.com/idom-team/idom/issues/569).
This is a shortcut that returns the Websocket's `path`.
@@ -48,7 +48,7 @@ from idom import component, html
from django_idom.hooks import use_location
@component
-def MyComponent():
+def my_component():
my_location = use_location()
return html.div(my_location)
```
diff --git a/docs/features/templatetag.md b/docs/features/templatetag.md
index 26a2f4ad..358d60cf 100644
--- a/docs/features/templatetag.md
+++ b/docs/features/templatetag.md
@@ -14,16 +14,16 @@ Integrated within Django IDOM, we bundle a template tag. Within this tag, you ca
```python title="views.py"
def example_view():
- context_vars = {"DontDoThis": "example_project.my_app.components.HelloWorld"}
+ context_vars = {"dont_do_this": "example_project.my_app.components.hello_world"}
return render(request, "my-template.html", context_vars)
```
```jinja title="my-template.html"
- {% component DontDoThis recipient="World" %}
+ {% component dont_do_this recipient="World" %}
- {% component "example_project.my_app.components.HelloWorld" recipient="World" %}
+ {% component "example_project.my_app.components.hello_world" recipient="World" %}
```
@@ -38,7 +38,7 @@ Integrated within Django IDOM, we bundle a template tag. Within this tag, you ca
```jinja title="my-template.html"
...
- {% component "example.components.MyComponent" class="my-html-class" key=123 %}
+ {% component "example.components.my_component" class="my-html-class" key=123 %}
...
```
@@ -54,14 +54,16 @@ Integrated within Django IDOM, we bundle a template tag. Within this tag, you ca
- {% component "example_project.my_app.components.HelloWorld" recipient="World" %}
- {% component "example_project.my_app_2.components.ClassComponent" class="bold small-font" %}
- {% component "example_project.my_app_3.components.SimpleComponent" %}
+ {% component "example_project.my_app.components.hello_world" recipient="World" %}
+ {% component "example_project.my_app_2.components.class_component" class="bold small-font" %}
+ {% component "example_project.my_app_3.components.simple_component" %}
```
But keep in mind, in scenarios where you are trying to create a Single Page Application (SPA) within Django, you will only have one central component within your `#!html ` tag.
+
+ Additionally, the components in the example above will not be able to interact with each other, except through database queries.
diff --git a/src/django_idom/templatetags/idom.py b/src/django_idom/templatetags/idom.py
index 7b8f3610..5e6b7ced 100644
--- a/src/django_idom/templatetags/idom.py
+++ b/src/django_idom/templatetags/idom.py
@@ -26,7 +26,7 @@ def component(_component_id_, **kwargs):
- {% component "example_project.my_app.components.HelloWorld" recipient="World" %}
+ {% component "example_project.my_app.components.hello_world" recipient="World" %}
"""
diff --git a/tests/test_app/components.py b/tests/test_app/components.py
index 687bfea2..a2491c17 100644
--- a/tests/test_app/components.py
+++ b/tests/test_app/components.py
@@ -4,12 +4,12 @@
@idom.component
-def HelloWorld():
+def hello_world():
return idom.html.h1({"id": "hello-world"}, "Hello World!")
@idom.component
-def Button():
+def button():
count, set_count = idom.hooks.use_state(0)
return idom.html.div(
idom.html.button(
@@ -24,7 +24,7 @@ def Button():
@idom.component
-def ParametrizedComponent(x, y):
+def parameterized_component(x, y):
total = x + y
return idom.html.h1({"id": "parametrized-component", "data-value": total}, total)
@@ -34,64 +34,64 @@ def ParametrizedComponent(x, y):
@idom.component
-def SimpleBarChart():
+def simple_bar_chart():
return VictoryBar()
@idom.component
-def UseWebsocket():
+def use_websocket():
ws = django_idom.hooks.use_websocket()
ws.scope = "..."
success = bool(ws.scope and ws.close and ws.disconnect and ws.view_id)
return idom.html.div(
{"id": "use-websocket", "data-success": success},
idom.html.hr(),
- f"UseWebsocket: {ws}",
+ f"use_websocket: {ws}",
idom.html.hr(),
)
@idom.component
-def UseScope():
+def use_scope():
scope = django_idom.hooks.use_scope()
success = len(scope) >= 10 and scope["type"] == "websocket"
return idom.html.div(
{"id": "use-scope", "data-success": success},
- f"UseScope: {scope}",
+ f"use_scope: {scope}",
idom.html.hr(),
)
@idom.component
-def UseLocation():
+def use_location():
location = django_idom.hooks.use_location()
success = bool(location)
return idom.html.div(
{"id": "use-location", "data-success": success},
- f"UseLocation: {location}",
+ f"use_location: {location}",
idom.html.hr(),
)
@idom.component
-def StaticCSS():
+def django_css():
return idom.html.div(
- {"id": "static-css"},
- django_idom.components.django_css("static-css-test.css"),
- idom.html.div({"style": {"display": "inline"}}, "StaticCSS: "),
+ {"id": "django-css"},
+ django_idom.components.django_css("django-css-test.css"),
+ idom.html.div({"style": {"display": "inline"}}, "django_css: "),
idom.html.button("This text should be blue."),
idom.html.hr(),
)
@idom.component
-def StaticJS():
+def django_js():
success = False
return idom.html._(
idom.html.div(
- {"id": "static-js", "data-success": success},
- f"StaticJS: {success}",
- django_idom.components.django_js("static-js-test.js"),
+ {"id": "django-js", "data-success": success},
+ f"django_js: {success}",
+ django_idom.components.django_js("django-js-test.js"),
),
idom.html.hr(),
)
diff --git a/tests/test_app/static/static-css-test.css b/tests/test_app/static/django-css-test.css
similarity index 61%
rename from tests/test_app/static/static-css-test.css
rename to tests/test_app/static/django-css-test.css
index d5565d70..af68e6ed 100644
--- a/tests/test_app/static/static-css-test.css
+++ b/tests/test_app/static/django-css-test.css
@@ -1,3 +1,3 @@
-#static-css button {
+#django-css button {
color: rgba(0, 0, 255, 1);
}
diff --git a/tests/test_app/static/django-js-test.js b/tests/test_app/static/django-js-test.js
new file mode 100644
index 00000000..1d59eb31
--- /dev/null
+++ b/tests/test_app/static/django-js-test.js
@@ -0,0 +1,3 @@
+let el = document.body.querySelector("#django-js");
+el.textContent = "django_js: True";
+el.dataset.success = "true";
diff --git a/tests/test_app/static/static-js-test.js b/tests/test_app/static/static-js-test.js
deleted file mode 100644
index b4423acf..00000000
--- a/tests/test_app/static/static-js-test.js
+++ /dev/null
@@ -1,3 +0,0 @@
-let el = document.body.querySelector("#static-js");
-el.textContent = "StaticJS: True";
-el.dataset.success = "true";
diff --git a/tests/test_app/templates/base.html b/tests/test_app/templates/base.html
index c597cdf9..e6960c14 100644
--- a/tests/test_app/templates/base.html
+++ b/tests/test_app/templates/base.html
@@ -12,15 +12,15 @@
IDOM Test Page
- {% component "test_app.components.HelloWorld" class="hello-world" %}
- {% component "test_app.components.Button" class="button" %}
- {% component "test_app.components.ParametrizedComponent" class="parametarized-component" x=123 y=456 %}
- {% component "test_app.components.SimpleBarChart" %}
- {% component "test_app.components.UseWebsocket" %}
- {% component "test_app.components.UseScope" %}
- {% component "test_app.components.UseLocation" %}
- {% component "test_app.components.StaticCSS" %}
- {% component "test_app.components.StaticJS" %}
+ {% component "test_app.components.hello_world" class="hello-world" %}
+ {% component "test_app.components.button" class="button" %}
+ {% component "test_app.components.parameterized_component" class="parametarized-component" x=123 y=456 %}
+ {% component "test_app.components.simple_bar_chart" %}
+ {% component "test_app.components.use_websocket" %}
+ {% component "test_app.components.use_scope" %}
+ {% component "test_app.components.use_location" %}
+ {% component "test_app.components.django_css" %}
+ {% component "test_app.components.django_js" %}
diff --git a/tests/test_app/tests/test_components.py b/tests/test_app/tests/test_components.py
index 33a8c6e8..8ed89efa 100644
--- a/tests/test_app/tests/test_components.py
+++ b/tests/test_app/tests/test_components.py
@@ -60,13 +60,13 @@ def test_use_location(self):
self.assertEqual(element.get_attribute("data-success"), "true")
def test_static_css(self):
- element = self.driver.find_element_by_css_selector("#static-css button")
+ element = self.driver.find_element_by_css_selector("#django-css button")
self.assertEqual(
element.value_of_css_property("color"), "rgba(0, 0, 255, 1)"
)
def test_static_js(self):
- element = self.driver.find_element_by_id("static-js")
+ element = self.driver.find_element_by_id("django-js")
self.assertEqual(element.get_attribute("data-success"), "true")
From 363c548b1a37a1be779e49e11792ea62d67da007 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 04:24:00 -0700
Subject: [PATCH 2/8] add settings.py to exclusive features
---
docs/features/settings.md | 27 +++++++++++++++++++++++++++
docs/installation/index.md | 14 +-------------
mkdocs.yml | 1 +
3 files changed, 29 insertions(+), 13 deletions(-)
create mode 100644 docs/features/settings.md
diff --git a/docs/features/settings.md b/docs/features/settings.md
new file mode 100644
index 00000000..1fabde33
--- /dev/null
+++ b/docs/features/settings.md
@@ -0,0 +1,27 @@
+Django IDOM uses your **Django project's** `settings.py` file to modify some behaviors of IDOM.
+
+Here are the configurable variables that are available.
+
+
+
+```python title="settings.py"
+# If "idom" cache is not configured, then we'll use "default" instead
+CACHES = {
+"idom": {"BACKEND": ...},
+}
+
+# Maximum seconds between two reconnection attempts that would cause the client give up.
+# 0 will disable reconnection.
+IDOM_WS_MAX_RECONNECT_TIMEOUT = 604800
+
+# The URL for IDOM to serve websockets
+IDOM_WEBSOCKET_URL = "idom/"
+```
+
+
+
+??? question "Do I need to modify my settings?"
+
+ The default configuration of IDOM is adequate for the majority of use cases.
+
+ You should only consider changing settings when the necessity arises.
\ No newline at end of file
diff --git a/docs/installation/index.md b/docs/installation/index.md
index a2a6e391..e0cdfc1e 100644
--- a/docs/installation/index.md
+++ b/docs/installation/index.md
@@ -43,19 +43,7 @@ INSTALLED_APPS = [
Below are a handful of values you can change within `settings.py` to modify the behavior of IDOM.
- ```python title="settings.py"
- # If "idom" cache is not configured, then we'll use "default" instead
- CACHES = {
- "idom": {"BACKEND": ...},
- }
-
- # Maximum seconds between two reconnection attempts that would cause the client give up.
- # 0 will disable reconnection.
- IDOM_WS_MAX_RECONNECT_TIMEOUT = 604800
-
- # The URL for IDOM to serve websockets
- IDOM_WEBSOCKET_URL = "idom/"
- ```
+ {% include-markdown "../features/settings.md" start="" end="" %}
---
diff --git a/mkdocs.yml b/mkdocs.yml
index 50cef329..a1673ffb 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -12,6 +12,7 @@ nav:
- Components: features/components.md
- Hooks: features/hooks.md
- Template Tag: features/templatetag.md
+ - Settings: features/settings.md
- Contribute:
- Code: contribute/django-idom.md
- Docs: contribute/docs.md
From 0b9b39007e1a7968602404c4a21370a94bb25d83 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 04:40:12 -0700
Subject: [PATCH 3/8] change light/dark mode icons
---
mkdocs.yml | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/mkdocs.yml b/mkdocs.yml
index a1673ffb..9cf9d38b 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -25,14 +25,14 @@ theme:
- media: "(prefers-color-scheme: dark)"
scheme: slate
toggle:
- icon: material/toggle-switch
+ icon: material/white-balance-sunny
name: Switch to light mode
primary: deep-orange
accent: orange
- media: "(prefers-color-scheme: light)"
scheme: default
toggle:
- icon: material/toggle-switch-off-outline
+ icon: material/weather-night
name: Switch to dark mode
primary: black
features:
From 56006e249658c1ebe5057c5531afc7ed790046b3 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 05:10:18 -0700
Subject: [PATCH 4/8] create docs tests
---
.github/workflows/test-docs.yml | 15 +++++++++++++++
.github/workflows/{test.yml => test-src.yml} | 0
2 files changed, 15 insertions(+)
create mode 100644 .github/workflows/test-docs.yml
rename .github/workflows/{test.yml => test-src.yml} (100%)
diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml
new file mode 100644
index 00000000..a0c9f304
--- /dev/null
+++ b/.github/workflows/test-docs.yml
@@ -0,0 +1,15 @@
+name: Publish Docs
+on:
+ push:
+ branches:
+ - main
+jobs:
+ deploy:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@v2
+ - uses: actions/setup-python@v2
+ with:
+ python-version: 3.x
+ - run: pip install -r requirements/build-docs.txt
+ - run: mkdocs build --verbose
diff --git a/.github/workflows/test.yml b/.github/workflows/test-src.yml
similarity index 100%
rename from .github/workflows/test.yml
rename to .github/workflows/test-src.yml
From 0e20556c7b651afe552bd71bbee2bde65e20284b Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 05:12:55 -0700
Subject: [PATCH 5/8] configure test workflows properly
---
.github/workflows/test-docs.yml | 9 ++++++++-
.github/workflows/test-src.yml | 2 +-
2 files changed, 9 insertions(+), 2 deletions(-)
diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml
index a0c9f304..5bb4b62a 100644
--- a/.github/workflows/test-docs.yml
+++ b/.github/workflows/test-docs.yml
@@ -1,8 +1,15 @@
-name: Publish Docs
+name: Test Docs
+
on:
push:
branches:
- main
+ pull_request:
+ branches:
+ - main
+ schedule:
+ - cron: "0 0 * * *"
+
jobs:
deploy:
runs-on: ubuntu-latest
diff --git a/.github/workflows/test-src.yml b/.github/workflows/test-src.yml
index 2675c040..956b1040 100644
--- a/.github/workflows/test-src.yml
+++ b/.github/workflows/test-src.yml
@@ -1,4 +1,4 @@
-name: Test
+name: Test Source
on:
push:
From 148a448bfd21dfea4f94cced1f12cc5e7eb2a654 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 05:15:41 -0700
Subject: [PATCH 6/8] rename workflow/jobs
---
.github/workflows/test-docs.yml | 4 ++--
.github/workflows/test-src.yml | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.github/workflows/test-docs.yml b/.github/workflows/test-docs.yml
index 5bb4b62a..967f7c8c 100644
--- a/.github/workflows/test-docs.yml
+++ b/.github/workflows/test-docs.yml
@@ -1,4 +1,4 @@
-name: Test Docs
+name: Test
on:
push:
@@ -11,7 +11,7 @@ on:
- cron: "0 0 * * *"
jobs:
- deploy:
+ docs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
diff --git a/.github/workflows/test-src.yml b/.github/workflows/test-src.yml
index 956b1040..f5320f35 100644
--- a/.github/workflows/test-src.yml
+++ b/.github/workflows/test-src.yml
@@ -1,4 +1,4 @@
-name: Test Source
+name: Test
on:
push:
@@ -11,7 +11,7 @@ on:
- cron: "0 0 * * *"
jobs:
- test-python-versions:
+ source:
runs-on: ubuntu-latest
strategy:
matrix:
From 296f1d767e2c39f0a57b31b35a38c8c847ca99ae Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 05:41:30 -0700
Subject: [PATCH 7/8] remove alternative title on hooks page
---
docs/features/hooks.md | 2 --
1 file changed, 2 deletions(-)
diff --git a/docs/features/hooks.md b/docs/features/hooks.md
index b253e26f..bcabc183 100644
--- a/docs/features/hooks.md
+++ b/docs/features/hooks.md
@@ -1,5 +1,3 @@
-# Django Hooks
-
???+ tip "Looking for more hooks?"
Check out the [IDOM Core docs](https://idom-docs.herokuapp.com/docs/reference/hooks-api.html?highlight=hooks) on hooks!
From fab43de707a80b8b509f6e9f7447a75230893475 Mon Sep 17 00:00:00 2001
From: Archmonger <16909269+Archmonger@users.noreply.github.com>
Date: Sat, 2 Jul 2022 05:47:28 -0700
Subject: [PATCH 8/8] format all docs
---
docs/features/hooks.md | 3 ---
docs/features/settings.md | 4 ++--
docs/features/templatetag.md | 2 +-
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/docs/features/hooks.md b/docs/features/hooks.md
index bcabc183..7a0d8a99 100644
--- a/docs/features/hooks.md
+++ b/docs/features/hooks.md
@@ -16,8 +16,6 @@ def my_component():
return html.div(my_websocket)
```
-
-
## Use Scope
This is a shortcut that returns the Websocket's `scope`.
@@ -32,7 +30,6 @@ def my_component():
return html.div(my_scope)
```
-
## Use Location
??? info "This hook's behavior will be changed in a future update"
diff --git a/docs/features/settings.md b/docs/features/settings.md
index 1fabde33..b003ae3c 100644
--- a/docs/features/settings.md
+++ b/docs/features/settings.md
@@ -22,6 +22,6 @@ IDOM_WEBSOCKET_URL = "idom/"
??? question "Do I need to modify my settings?"
- The default configuration of IDOM is adequate for the majority of use cases.
+ The default configuration of IDOM is adequate for the majority of use cases.
- You should only consider changing settings when the necessity arises.
\ No newline at end of file
+ You should only consider changing settings when the necessity arises.
diff --git a/docs/features/templatetag.md b/docs/features/templatetag.md
index 358d60cf..5f917f92 100644
--- a/docs/features/templatetag.md
+++ b/docs/features/templatetag.md
@@ -62,7 +62,7 @@ Integrated within Django IDOM, we bundle a template tag. Within this tag, you ca
```
But keep in mind, in scenarios where you are trying to create a Single Page Application (SPA) within Django, you will only have one central component within your `#!html ` tag.
-
+
Additionally, the components in the example above will not be able to interact with each other, except through database queries.