Skip to content

Commit a74b22a

Browse files
Add README.md for D1 template
Created a new README.md file for the D1 template, based on the existing Durable Objects template README. The new README provides specific instructions and configurations for setting up and deploying a Django application using Cloudflare D1 with django-cf.
1 parent a51e6b5 commit a74b22a

File tree

1 file changed

+206
-1
lines changed

1 file changed

+206
-1
lines changed

templates/d1/README.md

Lines changed: 206 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,206 @@
1-
# Django + D1 Template for Cloudflare Workers
1+
# Django D1 Template for Cloudflare Workers
2+
3+
This template provides a starting point for running a Django application on Cloudflare Workers, utilizing Cloudflare D1 for serverless SQL database.
4+
5+
[![Deploy to Cloudflare](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/G4brym/django-cf/tree/main/templates/d1)
6+
7+
## Overview
8+
9+
This template is pre-configured to:
10+
- Use `django-cf` to bridge Django with Cloudflare's environment.
11+
- Employ Cloudflare D1 as the primary data store through the `django_cf.d1_binding` database engine.
12+
- Include a basic Django project structure within the `src/` directory.
13+
- Provide example worker entrypoint (`src/worker.py`).
14+
15+
## Project Structure
16+
17+
```
18+
template-root/
19+
|-> src/
20+
| |-> manage.py # Django management script
21+
| |-> worker.py # Cloudflare Worker entrypoint
22+
| |-> app/ # Your Django project (rename as needed)
23+
| | |-> settings.py # Django settings, configured for D1
24+
| | |-> urls.py # Django URLs, includes management endpoints
25+
| | |-> wsgi.py # WSGI application
26+
| |-> your_django_apps/ # Add your Django apps here
27+
| |-> vendor/ # Project dependencies (managed by vendor.txt)
28+
|-> staticfiles/ # Collected static files (after build)
29+
|-> .gitignore
30+
|-> package.json # For Node.js dependencies like wrangler
31+
|-> package-lock.json
32+
|-> requirements-dev.txt # Python dev dependencies
33+
|-> vendor.txt # Pip requirements for vendoring
34+
|-> wrangler.jsonc # Wrangler configuration
35+
```
36+
37+
## Setup and Deployment
38+
39+
1. **Install Dependencies:**
40+
* **Node.js & Wrangler:** Ensure you have Node.js and npm installed. Then install dependencies with this command:
41+
```bash
42+
npm install
43+
```
44+
* **Python Dependencies (Vendoring):**
45+
List your Python dependencies (including `django` and `django-cf`) in `vendor.txt`.
46+
```txt
47+
# vendor.txt
48+
django~=5.0
49+
django-cf
50+
tzdata # For timezone support
51+
# Add other dependencies here
52+
```
53+
Install them into the `src/vendor` directory:
54+
```bash
55+
pip install -t src/vendor -r vendor.txt
56+
```
57+
58+
* **Python Dependencies (Local Development):**
59+
List your Python dev dependencies (including `django` and `django-cf`) in `requirements-dev.txt`.
60+
```txt
61+
# requirements-dev.txt
62+
django==5.1.2
63+
django-cf
64+
# For local D1 API access during development (e.g., running migrations)
65+
# Add other dev dependencies here
66+
```
67+
Install them:
68+
```bash
69+
pip install -r requirements-dev.txt
70+
```
71+
72+
2. **Configure `wrangler.jsonc`:**
73+
Review and update `wrangler.jsonc` for your project. Key sections:
74+
* `name`: Your worker's name.
75+
* `main`: Should point to `src/worker.py`.
76+
* `compatibility_date`: Keep this up-to-date.
77+
* `d1_databases`:
78+
* `binding`: The name used to access the D1 database in your worker (e.g., "DB").
79+
* `database_name`: The name of your D1 database in the Cloudflare dashboard.
80+
* `database_id`: The ID of your D1 database.
81+
* `site`:
82+
* `bucket`: Points to `./staticfiles` for serving static assets.
83+
* `build`:
84+
* `command`: `"python src/manage.py collectstatic --noinput"` to automatically collect static files during deployment.
85+
86+
Example `d1_databases` configuration in `wrangler.jsonc`:
87+
```jsonc
88+
// ... other wrangler.jsonc configurations
89+
"d1_databases": [
90+
{
91+
"binding": "DB", // Must match CLOUDFLARE_BINDING in Django settings
92+
"database_name": "my-django-db",
93+
"database_id": "your-d1-database-id-here"
94+
}
95+
],
96+
// ...
97+
```
98+
99+
3. **Django Settings (`src/app/settings.py`):**
100+
The template should be configured to use D1 binding:
101+
```python
102+
# src/app/settings.py
103+
DATABASES = {
104+
'default': {
105+
'ENGINE': 'django_cf.d1_binding',
106+
# This name 'DB' must match the 'binding' in your wrangler.jsonc d1_databases section
107+
'CLOUDFLARE_BINDING': 'DB',
108+
}
109+
}
110+
111+
# Static files
112+
import os
113+
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
114+
STATIC_URL = '/static/'
115+
# STATIC_ROOT should point to the 'bucket' directory in wrangler.jsonc,
116+
# often one level above the 'src' directory.
117+
STATIC_ROOT = os.path.join(os.path.dirname(BASE_DIR), 'staticfiles', 'static')
118+
119+
# Optional: Settings for local development using D1 API
120+
# You can create a separate settings_dev.py or use environment variables
121+
# DATABASES_DEV = {
122+
# 'default': {
123+
# 'ENGINE': 'django_cf.d1_api',
124+
# 'CLOUDFLARE_DATABASE_ID': '<your_database_id>',
125+
# 'CLOUDFLARE_ACCOUNT_ID': '<your_account_id>',
126+
# 'CLOUDFLARE_TOKEN': '<your_d1_api_token>',
127+
# }
128+
# }
129+
```
130+
131+
4. **Worker Entrypoint (`src/worker.py`):**
132+
This file contains the main `on_fetch` handler for your Django application.
133+
```python
134+
from django_cf import DjangoCFAdapter
135+
136+
async def on_fetch(request, env):
137+
# Ensure your Django project's WSGI application is importable
138+
# For example, if your project is 'app' inside 'src':
139+
from app.wsgi import application # Import application inside on_fetch
140+
141+
# The DjangoCFAdapter requires the Django application and the environment (for D1 binding)
142+
adapter = DjangoCFAdapter(application, env)
143+
return await adapter.handle_request(request)
144+
```
145+
146+
5. **Deploy to Cloudflare:**
147+
```bash
148+
npx wrangler deploy
149+
```
150+
This command will also run the `collectstatic` command if configured in `wrangler.jsonc`.
151+
152+
## Running Management Commands
153+
154+
* **Migrations & `createsuperuser` (Local Development - Recommended for D1):**
155+
For D1, it's often easiest and safest to run migrations and `createsuperuser` from your local machine by configuring your development Django settings to use the D1 API.
156+
157+
1. Ensure you have `django-cf` and your other dependencies installed in your local Python environment (`pip install -r requirements-dev.txt`).
158+
2. Set up your Django settings for local D1 API access. You can do this by:
159+
* Creating a `settings_dev.py` and using `python src/manage.py migrate --settings=app.settings_dev`.
160+
* Or, by temporarily modifying your main `settings.py` (ensure you don't commit API keys).
161+
* Or, by using environment variables to supply D1 API credentials to your settings.
162+
163+
Example local D1 API settings in `settings_dev.py` (place it alongside your main `settings.py`):
164+
```python
165+
# app/settings_dev.py
166+
from .settings import * # Inherit base settings
167+
168+
DATABASES = {
169+
'default': {
170+
'ENGINE': 'django_cf.d1_api',
171+
'CLOUDFLARE_DATABASE_ID': 'your-actual-d1-database-id',
172+
'CLOUDFLARE_ACCOUNT_ID': 'your-cloudflare-account-id',
173+
'CLOUDFLARE_TOKEN': 'your-cloudflare-d1-api-token', # Ensure this token has D1 Read/Write permissions
174+
}
175+
}
176+
```
177+
3. Run commands:
178+
```bash
179+
# From the template root directory
180+
python src/manage.py migrate --settings=app.settings_dev
181+
python src/manage.py createsuperuser --settings=app.settings_dev
182+
```
183+
184+
* **Via a Worker Endpoint (Use with Extreme Caution):**
185+
While possible, running migrations or creating users directly via a worker endpoint is generally **not recommended for D1** due to the direct database access available locally via the D1 API. If you absolutely must, you can adapt the management command endpoints from the Durable Objects template (`src/app/urls.py`), but ensure they are **extremely well-secured**.
186+
The main risk is exposing sensitive operations over HTTP and potential complexities with the worker environment.
187+
188+
If you choose this path, remember:
189+
* The worker needs the D1 binding (`env`) passed to the `DjangoCFAdapter` and accessible to your management command functions.
190+
* Secure the endpoints robustly (e.g., IP restrictions, strong authentication tokens, not just Django's `is_superuser` if the admin user might not exist yet).
191+
192+
## Development Notes
193+
194+
* **D1 Limitations:**
195+
* **Transactions are disabled** for D1. Every query is committed immediately. This is a fundamental aspect of D1.
196+
* The D1 backend has some limitations compared to traditional SQLite or other SQL databases. Many advanced ORM features or direct SQL functions (especially those used in Django Admin) might not be fully supported. Refer to the `django-cf` README and official Cloudflare D1 documentation.
197+
* Django Admin functionality might be limited.
198+
* **Local Testing with D1:**
199+
* Wrangler allows local development and can simulate D1 access. `npx wrangler dev --remote` can connect to your actual D1 database for more accurate testing.
200+
* Using the D1 API for local management tasks (as described above) is the most common workflow.
201+
* **Security:**
202+
* If you implement management command endpoints on your worker, secure them rigorously.
203+
* Protect your Cloudflare API tokens and credentials.
204+
205+
---
206+
*For more details on `django-cf` features and configurations, refer to the main [django-cf GitHub repository](https://github.com/G4brym/django-cf).*

0 commit comments

Comments
 (0)