From 5cdbd0716a7a538cced36e3ae329a918cb89df5c Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Tue, 11 Jan 2022 22:36:04 -0800 Subject: [PATCH 01/10] Use urlpatterns for HTTP URLS --- src/django_idom/__init__.py | 5 ++- src/django_idom/config.py | 7 ++--- src/django_idom/http/__init__.py | 0 src/django_idom/http/urls.py | 13 ++++++++ src/django_idom/{ => http}/views.py | 2 +- src/django_idom/paths.py | 31 ------------------- src/django_idom/templatetags/idom.py | 8 ++--- src/django_idom/websocket/__init__.py | 0 .../consumer.py} | 2 +- src/django_idom/websocket/paths.py | 13 ++++++++ tests/test_app/urls.py | 6 ++-- 11 files changed, 38 insertions(+), 49 deletions(-) create mode 100644 src/django_idom/http/__init__.py create mode 100644 src/django_idom/http/urls.py rename src/django_idom/{ => http}/views.py (95%) delete mode 100644 src/django_idom/paths.py create mode 100644 src/django_idom/websocket/__init__.py rename src/django_idom/{websocket_consumer.py => websocket/consumer.py} (98%) create mode 100644 src/django_idom/websocket/paths.py diff --git a/src/django_idom/__init__.py b/src/django_idom/__init__.py index 90a4aba1..6ca44600 100644 --- a/src/django_idom/__init__.py +++ b/src/django_idom/__init__.py @@ -1,5 +1,4 @@ -from .paths import IDOM_WEB_MODULES_PATH, IDOM_WEBSOCKET_PATH - +from .websocket.paths import IDOM_WEBSOCKET_PATH __version__ = "0.0.1" -__all__ = ["IDOM_WEB_MODULES_PATH", "IDOM_WEBSOCKET_PATH"] +__all__ = ["IDOM_WEBSOCKET_PATH"] diff --git a/src/django_idom/config.py b/src/django_idom/config.py index 1d527a9e..197f0cf5 100644 --- a/src/django_idom/config.py +++ b/src/django_idom/config.py @@ -7,11 +7,10 @@ IDOM_REGISTERED_COMPONENTS: Dict[str, ComponentConstructor] = {} -IDOM_BASE_URL = getattr(settings, "IDOM_BASE_URL", "_idom/") -IDOM_WEBSOCKET_URL = IDOM_BASE_URL + "websocket/" -IDOM_WEB_MODULES_URL = IDOM_BASE_URL + "web_module/" +IDOM_WEBSOCKET_URL = getattr(settings, "IDOM_WEBSOCKET_URL", "idom/") IDOM_WS_MAX_RECONNECT_DELAY = getattr(settings, "IDOM_WS_MAX_RECONNECT_DELAY", 604800) +# Determine if using Django caching or LRU cache _CACHES = getattr(settings, "CACHES", {}) if _CACHES: if "idom_web_modules" in getattr(settings, "CACHES", {}): @@ -22,7 +21,7 @@ IDOM_WEB_MODULE_CACHE = None -# the LRU cache size for the route serving IDOM_WEB_MODULES_DIR files +# LRU cache size, if not using Django caching IDOM_WEB_MODULE_LRU_CACHE_SIZE = getattr( settings, "IDOM_WEB_MODULE_LRU_CACHE_SIZE", None ) diff --git a/src/django_idom/http/__init__.py b/src/django_idom/http/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/django_idom/http/urls.py b/src/django_idom/http/urls.py new file mode 100644 index 00000000..c73a6ca0 --- /dev/null +++ b/src/django_idom/http/urls.py @@ -0,0 +1,13 @@ +from django.urls import path, include + +from . import views + +app_name = "idom" + +urlpatterns = [ + path( + "web_module/", + views.web_modules_file, + name="web_modules", + ) +] diff --git a/src/django_idom/views.py b/src/django_idom/http/views.py similarity index 95% rename from src/django_idom/views.py rename to src/django_idom/http/views.py index 7dd9578a..a015a937 100644 --- a/src/django_idom/views.py +++ b/src/django_idom/http/views.py @@ -6,7 +6,7 @@ from django.http import HttpRequest, HttpResponse from idom.config import IDOM_WED_MODULES_DIR -from .config import IDOM_WEB_MODULE_CACHE, IDOM_WEB_MODULE_LRU_CACHE_SIZE +from ..config import IDOM_WEB_MODULE_CACHE, IDOM_WEB_MODULE_LRU_CACHE_SIZE if IDOM_WEB_MODULE_CACHE is None: diff --git a/src/django_idom/paths.py b/src/django_idom/paths.py deleted file mode 100644 index 184182c3..00000000 --- a/src/django_idom/paths.py +++ /dev/null @@ -1,31 +0,0 @@ -from django.urls import path - -from . import views -from .config import IDOM_WEB_MODULES_URL, IDOM_WEBSOCKET_URL -from .websocket_consumer import IdomAsyncWebsocketConsumer - - -IDOM_WEBSOCKET_PATH = path( - IDOM_WEBSOCKET_URL + "/", - IdomAsyncWebsocketConsumer.as_asgi(), - name="idom_websocket", -) -"""A URL resolver for :class:`IdomAsyncWebsocketConsumer` - -While this is relatively uncommon in most Django apps, because the URL of the -websocket must be defined by the setting ``IDOM_WEBSOCKET_URL``. There's no need -to allow users to configure the URL themselves. -""" - - -IDOM_WEB_MODULES_PATH = path( - IDOM_WEB_MODULES_URL + "", - views.web_modules_file, - name="idom_web_modules", -) -"""A URL resolver for static web modules required by IDOM - -While this is relatively uncommon in most Django apps, because the URL of the -websocket must be defined by the setting ``IDOM_WEBSOCKET_URL``. There's no need -to allow users to configure the URL themselves. -""" diff --git a/src/django_idom/templatetags/idom.py b/src/django_idom/templatetags/idom.py index d6692b5b..d21620bc 100644 --- a/src/django_idom/templatetags/idom.py +++ b/src/django_idom/templatetags/idom.py @@ -3,15 +3,13 @@ from uuid import uuid4 from django import template +from django.urls import reverse -from django_idom.config import ( - IDOM_WEB_MODULES_URL, - IDOM_WEBSOCKET_URL, - IDOM_WS_MAX_RECONNECT_DELAY, -) +from django_idom.config import IDOM_WEBSOCKET_URL, IDOM_WS_MAX_RECONNECT_DELAY from django_idom.utils import _register_component +IDOM_WEB_MODULES_URL = reverse("idom:web_modules", args=["x"])[:-1][1:] register = template.Library() diff --git a/src/django_idom/websocket/__init__.py b/src/django_idom/websocket/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/src/django_idom/websocket_consumer.py b/src/django_idom/websocket/consumer.py similarity index 98% rename from src/django_idom/websocket_consumer.py rename to src/django_idom/websocket/consumer.py index 349a8366..79f09d08 100644 --- a/src/django_idom/websocket_consumer.py +++ b/src/django_idom/websocket/consumer.py @@ -12,7 +12,7 @@ from idom.core.dispatcher import dispatch_single_view from idom.core.layout import Layout, LayoutEvent -from .config import IDOM_REGISTERED_COMPONENTS +from ..config import IDOM_REGISTERED_COMPONENTS _logger = logging.getLogger(__name__) diff --git a/src/django_idom/websocket/paths.py b/src/django_idom/websocket/paths.py new file mode 100644 index 00000000..1e1f2d74 --- /dev/null +++ b/src/django_idom/websocket/paths.py @@ -0,0 +1,13 @@ +from django.urls import path + +from ..config import IDOM_WEBSOCKET_URL +from .consumer import IdomAsyncWebsocketConsumer + + +IDOM_WEBSOCKET_PATH = path( + IDOM_WEBSOCKET_URL + "/", IdomAsyncWebsocketConsumer.as_asgi() +) +"""A URL path for :class:`IdomAsyncWebsocketConsumer`. + +Required in order for IDOM to know the websocket path. +""" diff --git a/tests/test_app/urls.py b/tests/test_app/urls.py index 1ea0c99b..525659ea 100644 --- a/tests/test_app/urls.py +++ b/tests/test_app/urls.py @@ -18,15 +18,13 @@ 2. Add a URL to urlpatterns: path('blog/', include('blog.urls')) """ from django.contrib import admin -from django.urls import path - -from django_idom import IDOM_WEB_MODULES_PATH +from django.urls import include, path from .views import base_template urlpatterns = [ path("", base_template), - IDOM_WEB_MODULES_PATH, + path("idom/", include("django_idom.http.urls")), path("admin/", admin.site.urls), ] From 6a991759ea787ef05b9d03116fd601f9f52e0e82 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Tue, 11 Jan 2022 23:17:42 -0800 Subject: [PATCH 02/10] Clean up readme --- README.md | 186 ++++++++++++++++++++---------------------------------- 1 file changed, 67 insertions(+), 119 deletions(-) diff --git a/README.md b/README.md index 928c33a9..898ae47e 100644 --- a/README.md +++ b/README.md @@ -27,65 +27,53 @@ interfaces in pure Python. src="https://mybinder.org/badge_logo.svg"/> -# Install Django IDOM +# Quick Example -```bash -pip install django-idom -``` +## `example_app/components.py` -# Django Integration +This is where you'll define your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should +feel free to organize your component modules you wish. Any components created will ultimately be referenced +by Python dotted path in `your-template.html`. -To integrate IDOM into your application you'll need to modify or add the following files to `your_project`: +```python +import idom -``` -your_project/ -├── __init__.py -├── asgi.py -├── settings.py -├── urls.py -└── example_app/ - ├── __init__.py - ├── components.py - ├── templates/ - │ └── your-template.html - └── urls.py +@idom.component +def Hello(websocket, greeting_recipient): # Names are CamelCase by ReactJS convention + return idom.html.header(f"Hello {greeting_recipient}!") ``` -## `asgi.py` +## `example_app/templates/your-template.html` -Follow the [`channels`](https://channels.readthedocs.io/en/stable/) -[installation guide](https://channels.readthedocs.io/en/stable/installation.html) in -order to create ASGI websockets within Django. Then, we will add a path for IDOM's -websocket consumer using `IDOM_WEBSOCKET_PATH`. +In your templates, you may add IDOM components into your HTML by using the `idom_component` +template tag. This tag requires the dotted path to the component function. Additonally, you can +pass in keyworded arguments into your component function. -_Note: If you wish to change the route where this websocket is served from, see the -available [settings](#settingspy)._ +In context this will look a bit like the following... -```python +```jinja +{% load idom %} -import os + + + + ... + {% idom_component "my_django_project.example_app.components.Hello" greeting_recipient="World" %} + + +``` -from django.core.asgi import get_asgi_application +# Installation -from django_idom import IDOM_WEBSOCKET_PATH +Install `django-idom` via pip. -os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_app.settings") +```bash +pip install django-idom +``` -# Fetch ASGI application before importing dependencies that require ORM models. -http_asgi_app = get_asgi_application() +--- -from channels.auth import AuthMiddlewareStack -from channels.routing import ProtocolTypeRouter, URLRouter - -application = ProtocolTypeRouter( - { - "http": http_asgi_app, - "websocket": SessionMiddlewareStack( - AuthMiddlewareStack(URLRouter([IDOM_WEBSOCKET_PATH])) - ), - } -) -``` +You'll also need to modify a few files in your Django project... ## `settings.py` @@ -100,20 +88,9 @@ INSTALLED_APPS = [ ] ``` -You may configure additional options as well: +You may configure additional options as well... ```python -# the base URL for all IDOM-releated resources -IDOM_BASE_URL: str = "_idom/" - -# Set cache size limit for loading JS files for IDOM. -# Only applies when not using Django's caching framework (see below). -IDOM_WEB_MODULE_LRU_CACHE_SIZE: int | None = None - -# Maximum seconds between two reconnection attempts that would cause the client give up. -# 0 will disable reconnection. -IDOM_WS_MAX_RECONNECT_DELAY: int = 604800 - # Configure a cache for loading JS files CACHES = { # Configure a cache for loading JS files for IDOM @@ -121,89 +98,60 @@ CACHES = { # If the above cache is not configured, then we'll use the "default" instead "default": {"BACKEND": ...}, } + +# If your project has no caching configured, django-idom will use an in-memory +# LRU cache for caching JavaScript. +IDOM_WEB_MODULE_LRU_CACHE_SIZE: int | None = None + +# Maximum seconds between two reconnection attempts that would cause the client give up. +# 0 will disable reconnection. +IDOM_WS_MAX_RECONNECT_DELAY: int = 604800 + +# The URL for IDOM to serve its Websockets +IDOM_WEBSOCKET_URL: str = "idom/" ``` ## `urls.py` -You'll need to include IDOM's static web modules path using `IDOM_WEB_MODULES_PATH`. -Similarly to the `IDOM_WEBSOCKET_PATH`. If you wish to change the route where this -websocket is served from, see the available [settings](#settings.py). +Add Django-IDOM http URLs to your `urlpatterns`. ```python -from django_idom import IDOM_WEB_MODULES_PATH - urlpatterns = [ - IDOM_WEB_MODULES_PATH, + path("idom/", include("django_idom.http.urls")), ... ] ``` -## `example_app/components.py` - -This is where, by a convention similar to that of -[`views.py`](https://docs.djangoproject.com/en/3.2/topics/http/views/), you'll define -your [IDOM](https://github.com/idom-team/idom) components. Ultimately though, you should -feel free to organize your component modules you wish. The components created here will -ultimately be referenced by name in `your-template.html`. `your-template.html`. - -```python -import idom - -@idom.component -def Hello(websocket, greeting_recipient): # component names are camelcase by convention - return idom.html.header(f"Hello {greeting_recipient}!") -``` - -## `example_app/templates/your-template.html` - -In your templates, you may inject a view of an IDOM component into your templated HTML -by using the `idom_component` template tag. This tag which requires the name of a component -to render (of the form `module_name.ComponentName`) and keyword arguments you'd like to -pass it from the template. - -```python -idom_component module_name.ComponentName param_1="something" param_2="something-else" -``` +## `asgi.py` -In context this will look a bit like the following... +If you do not have an `asgi.py`, first follow the [`channels` installation guide](https://channels.readthedocs.io/en/stable/installation.html) in +order to create websockets within Django. -```jinja -{% load idom %} +We will add IDOM's websocket consumer path using `IDOM_WEBSOCKET_PATH`. - - - - ... - {% idom_component "your_project.example_app.components.Hello" greeting_recipient="World" %} - - -``` - -## `example_app/views.py` - -You can then serve `your-template.html` from a view just -[like any other](https://docs.djangoproject.com/en/3.2/intro/tutorial03/#write-views-that-actually-do-something). +_Note: If you wish to change the route where this websocket is served from, see the +available [settings](#settingspy)._ ```python -from django.shortcuts import render - -def your_view(request): - context = {} - return render(request, "your-template.html", context) -``` -## `example_app/urls.py` +import os +from django.core.asgi import get_asgi_application +from django_idom import IDOM_WEBSOCKET_PATH -Include your view in the list of urlpatterns +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_app.settings") +http_asgi_app = get_asgi_application() -```python -from django.urls import path -from .views import your_view # define this view like any other HTML template view +from channels.auth import AuthMiddlewareStack +from channels.routing import ProtocolTypeRouter, URLRouter -urlpatterns = [ - path("", your_view), - ... -] +application = ProtocolTypeRouter( + { + "http": http_asgi_app, + "websocket": SessionMiddlewareStack( + AuthMiddlewareStack(URLRouter([IDOM_WEBSOCKET_PATH])) + ), + } +) ``` # Developer Guide From b48e881b4376083760bfb2f3ae3c2ed1e0a7f333 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Tue, 11 Jan 2022 23:26:31 -0800 Subject: [PATCH 03/10] expose IdomWebsocket via django_idom --- README.md | 10 ++++++---- src/django_idom/__init__.py | 4 +++- src/django_idom/websocket/consumer.py | 4 ++-- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 898ae47e..537b4242 100644 --- a/README.md +++ b/README.md @@ -36,11 +36,13 @@ feel free to organize your component modules you wish. Any components created wi by Python dotted path in `your-template.html`. ```python -import idom +from idom import component, html +from django_idom import IdomWebsocket -@idom.component -def Hello(websocket, greeting_recipient): # Names are CamelCase by ReactJS convention - return idom.html.header(f"Hello {greeting_recipient}!") + +@component +def Hello(websocket: IdomWebsocket, greeting_recipient): # Names are CamelCase by ReactJS convention + return html.header(f"Hello {greeting_recipient}!") ``` ## `example_app/templates/your-template.html` diff --git a/src/django_idom/__init__.py b/src/django_idom/__init__.py index 6ca44600..f94066ea 100644 --- a/src/django_idom/__init__.py +++ b/src/django_idom/__init__.py @@ -1,4 +1,6 @@ +from .websocket.consumer import IdomWebsocket from .websocket.paths import IDOM_WEBSOCKET_PATH + __version__ = "0.0.1" -__all__ = ["IDOM_WEBSOCKET_PATH"] +__all__ = ["IDOM_WEBSOCKET_PATH", "IdomWebsocket"] diff --git a/src/django_idom/websocket/consumer.py b/src/django_idom/websocket/consumer.py index 79f09d08..180d6dd1 100644 --- a/src/django_idom/websocket/consumer.py +++ b/src/django_idom/websocket/consumer.py @@ -19,7 +19,7 @@ @dataclass -class WebsocketConnection: +class IdomWebsocket: scope: dict close: Callable[[Optional[int]], Awaitable[None]] disconnect: Callable[[int], Awaitable[None]] @@ -67,7 +67,7 @@ async def _run_dispatch_loop(self): component_kwargs = json.loads(query_dict.get("kwargs", "{}")) # Provide developer access to parts of this websocket - socket = WebsocketConnection(self.scope, self.close, self.disconnect, view_id) + socket = IdomWebsocket(self.scope, self.close, self.disconnect, view_id) try: component_instance = component_constructor(socket, **component_kwargs) From 0d8640da44d805565baa5c67d18dbfab9d8d3e81 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Tue, 11 Jan 2022 23:27:14 -0800 Subject: [PATCH 04/10] styling fixes --- src/django_idom/http/urls.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/django_idom/http/urls.py b/src/django_idom/http/urls.py index c73a6ca0..019a603e 100644 --- a/src/django_idom/http/urls.py +++ b/src/django_idom/http/urls.py @@ -1,7 +1,8 @@ -from django.urls import path, include +from django.urls import path from . import views + app_name = "idom" urlpatterns = [ From 6e7f2693a0b287e780c985bafb98727d1e02cda8 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Fri, 14 Jan 2022 01:39:13 -0800 Subject: [PATCH 05/10] add Django hyperlinks --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 537b4242..0ad36fcd 100644 --- a/README.md +++ b/README.md @@ -45,7 +45,7 @@ def Hello(websocket: IdomWebsocket, greeting_recipient): # Names are CamelCase return html.header(f"Hello {greeting_recipient}!") ``` -## `example_app/templates/your-template.html` +## [`example_app/templates/your-template.html`](https://docs.djangoproject.com/en/dev/topics/templates/) In your templates, you may add IDOM components into your HTML by using the `idom_component` template tag. This tag requires the dotted path to the component function. Additonally, you can @@ -77,7 +77,7 @@ pip install django-idom You'll also need to modify a few files in your Django project... -## `settings.py` +## [`settings.py`](https://docs.djangoproject.com/en/dev/topics/settings/) In your settings you'll need to add `django_idom` to the [`INSTALLED_APPS`](https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-INSTALLED_APPS) @@ -113,7 +113,7 @@ IDOM_WS_MAX_RECONNECT_DELAY: int = 604800 IDOM_WEBSOCKET_URL: str = "idom/" ``` -## `urls.py` +## [`urls.py`](https://docs.djangoproject.com/en/dev/topics/http/urls/) Add Django-IDOM http URLs to your `urlpatterns`. @@ -124,7 +124,7 @@ urlpatterns = [ ] ``` -## `asgi.py` +## [`asgi.py`](https://docs.djangoproject.com/en/dev/howto/deployment/asgi/) If you do not have an `asgi.py`, first follow the [`channels` installation guide](https://channels.readthedocs.io/en/stable/installation.html) in order to create websockets within Django. From 524215841bcdfffac9a9f305f47ae576f3f1cf3c Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Fri, 14 Jan 2022 01:40:39 -0800 Subject: [PATCH 06/10] add type hints to readme example --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ad36fcd..44041a44 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ from django_idom import IdomWebsocket @component -def Hello(websocket: IdomWebsocket, greeting_recipient): # Names are CamelCase by ReactJS convention +def Hello(websocket: IdomWebsocket, greeting_recipient: str): # Names are CamelCase by ReactJS convention return html.header(f"Hello {greeting_recipient}!") ``` From e0193c6cc16b0a422dcdac650dbc5c48496a81f6 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Fri, 14 Jan 2022 01:42:35 -0800 Subject: [PATCH 07/10] remove double relative imports --- src/django_idom/http/views.py | 2 +- src/django_idom/websocket/consumer.py | 2 +- src/django_idom/websocket/paths.py | 3 ++- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/django_idom/http/views.py b/src/django_idom/http/views.py index a015a937..ed321f40 100644 --- a/src/django_idom/http/views.py +++ b/src/django_idom/http/views.py @@ -6,7 +6,7 @@ from django.http import HttpRequest, HttpResponse from idom.config import IDOM_WED_MODULES_DIR -from ..config import IDOM_WEB_MODULE_CACHE, IDOM_WEB_MODULE_LRU_CACHE_SIZE +from django_idom.config import IDOM_WEB_MODULE_CACHE, IDOM_WEB_MODULE_LRU_CACHE_SIZE if IDOM_WEB_MODULE_CACHE is None: diff --git a/src/django_idom/websocket/consumer.py b/src/django_idom/websocket/consumer.py index 180d6dd1..8f773a38 100644 --- a/src/django_idom/websocket/consumer.py +++ b/src/django_idom/websocket/consumer.py @@ -12,7 +12,7 @@ from idom.core.dispatcher import dispatch_single_view from idom.core.layout import Layout, LayoutEvent -from ..config import IDOM_REGISTERED_COMPONENTS +from django_idom.config import IDOM_REGISTERED_COMPONENTS _logger = logging.getLogger(__name__) diff --git a/src/django_idom/websocket/paths.py b/src/django_idom/websocket/paths.py index 1e1f2d74..0d2920e0 100644 --- a/src/django_idom/websocket/paths.py +++ b/src/django_idom/websocket/paths.py @@ -1,6 +1,7 @@ from django.urls import path -from ..config import IDOM_WEBSOCKET_URL +from django_idom.config import IDOM_WEBSOCKET_URL + from .consumer import IdomAsyncWebsocketConsumer From c11387b204ed6f1f925c1ed036a128c9776622d1 Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Fri, 14 Jan 2022 01:46:11 -0800 Subject: [PATCH 08/10] link top dev docs for installed apps --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 44041a44..ca652e85 100644 --- a/README.md +++ b/README.md @@ -80,7 +80,7 @@ You'll also need to modify a few files in your Django project... ## [`settings.py`](https://docs.djangoproject.com/en/dev/topics/settings/) In your settings you'll need to add `django_idom` to the -[`INSTALLED_APPS`](https://docs.djangoproject.com/en/3.2/ref/settings/#std:setting-INSTALLED_APPS) +[`INSTALLED_APPS`](https://docs.djangoproject.com/en/dev/ref/settings/#std:setting-INSTALLED_APPS) list: ```python From bc4cd37d57950112c547d899e750d4a26e70692d Mon Sep 17 00:00:00 2001 From: Archmonger <16909269+Archmonger@users.noreply.github.com> Date: Thu, 20 Jan 2022 00:04:01 -0800 Subject: [PATCH 09/10] clean up static tag --- src/django_idom/templates/idom/component.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/django_idom/templates/idom/component.html b/src/django_idom/templates/idom/component.html index e471c6a9..8509bceb 100644 --- a/src/django_idom/templates/idom/component.html +++ b/src/django_idom/templates/idom/component.html @@ -1,7 +1,7 @@ {% load static %}