Datasette is implemented as an ASGI application.
Django can be run and deployed using ASGI.
At the DjangoCon Sprints this morning I figured out how to run Datasette inside a Django application, talking to the same SQLite databases as Django itself.
Run this in the same environment as your Django application (or add it to requirements.txt
or similar):
pip install datasette
Django projects have an asgi.py
module automatically generated for them when the project is created.
Replace its content with the following (careful to replace my_django_application.settings
with the correct value):
from datasette.app import Datasette
from django.core.asgi import get_asgi_application
from django.db import connections
import os
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "my_django_application.settings")
datasette_application = Datasette(
[
str(db["NAME"])
for db in connections.databases.values()
if db["ENGINE"] == "django.db.backends.sqlite3"
],
settings={
"base_url": "/datasette/",
},
).app()
django_application = get_asgi_application()
async def application(scope, receive, send):
if scope["type"] == "http" and scope.get("path").startswith("/datasette/"):
await datasette_application(scope, receive, send)
else:
await django_application(scope, receive, send)
Prior to this change, the file contained application = get_asgi_application()
. application
is the ASGI application that will be served.
This code replaces that with a tiny ASGI app that looks at the incoming scope["path"]
and, if it starts with /datasette/
, sends it to the Datasette ASGI application. All other requests are sent to Django.
The Datasette()
constructor at the start finds all SQLite databases that have been configured for Django, extracts their file path (db["NAME"]
is a path object for SQLite databases) and passes that to the Datasette constructor.
It also sets base_url
to /datasette/
so that Datasette will know how to generate correct URLs when it is mounted at that path, as opposed to the root /
path of the server.
Since this is an ASGI app, running ./manage.py runserver
will no longer do the right thing.
Instead, you need to install and use an ASGI server to run Django.
I like Uvicorn for this.
Install it with pip install uvicorn
, then start a local Django server running with:
uvicorn my_django_application.asgi:application
Add --reload
to cause it to automatically reload any time a file on disk is changed:
uvicorn my_django_application.asgi:application --reload
With this in place, browsing to http://127.0.0.1:8000/datasette/
will provide a Datasette interface for running read-only queries against your Django SQLite databases.
Created 2022-10-20T11:01:36-07:00, updated 2022-10-20T12:30:54-07:00 · History · Edit