Skip to content

Commit 9040083

Browse files
dnwparkmsullivan
andauthored
Add django examples (#1436)
### Description <!-- ✍️ Write a short summary of your work. Screenshots and videos are welcome! --> ### Demo URL <!-- Provide a URL to a live deployment where we can test your PR. If a demo isn't possible feel free to omit this section. --> ### Type of Change - [x] New Example - [ ] Example updates (Bug fixes, new features, etc.) - [ ] Other (changes to the codebase, but not to examples) ### New Example Checklist - [ ] 🛫 `npm run new-example` was used to create the example - [x] 📚 The template wasn't used but I carefuly read the [Adding a new example](https://github.com/vercel/examples#adding-a-new-example) steps and implemented them in the example - [ ] 📱 Is it responsive? Are mobile and tablets considered? --------- Co-authored-by: Michael J. Sullivan <sully@msully.net>
1 parent 2c854cc commit 9040083

53 files changed

Lines changed: 1230 additions & 259 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

python/django-notes/.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
db.sqlite3
2+
__pycache__/
3+
*.pyc
4+
.env
5+
.env.local
6+
.vercel
7+
.env*.local

python/django-notes/README.md

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
---
2+
name: Django Notes
3+
slug: django-notes
4+
description: A simple note-taking app built with Django, using SQLite locally and Postgres on Vercel.
5+
framework: Django
6+
useCase: Starter
7+
database: Postgres
8+
deployUrl: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fpython%2Fdjango-notes&project-name=django-notes&repository-name=django-notes&demo-title=Django%20Notes&demo-description=A%20simple%20note-taking%20app%20built%20with%20Django.&demo-url=https%3A%2F%2Fdjango-notes.vercel.app%2F&products=%5B%7B%22type%22%3A%22integration%22%2C%22group%22%3A%22postgres%22%7D%5D
9+
demoUrl: https://django-notes.vercel.app/
10+
relatedTemplates:
11+
- django
12+
- django-rest-framework
13+
---
14+
15+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fpython%2Fdjango-notes&project-name=django-notes&repository-name=django-notes&demo-title=Django%20Notes&demo-description=A%20simple%20note-taking%20app%20built%20with%20Django.&demo-url=https%3A%2F%2Fdjango-notes.vercel.app%2F&products=%5B%7B%22type%22%3A%22integration%22%2C%22group%22%3A%22postgres%22%7D%5D)
16+
17+
# Django Notes
18+
19+
A simple note-taking app built with Django, demonstrating server-side rendering, URL routing, forms, and ORM with SQLite locally and Postgres on Vercel.
20+
21+
## Demo
22+
23+
https://django-notes.vercel.app/
24+
25+
## How it Works
26+
27+
This example uses Django's ORM, templates, and `staticfiles` app, served via WSGI on Vercel. The database defaults to SQLite locally and switches to Postgres when `DATABASE_URL` is set — Vercel automatically provisions this environment variable when you add a Postgres database. You can add a database during project import or later from the Storage tab.
28+
29+
Migrations run automatically on each deploy via `[tool.vercel.scripts]` in `pyproject.toml`. Because of this, you should use a database provider that supports branching (like Neon) so that preview deployments run migrations against an isolated branch rather than your production database.
30+
31+
Setting `READ_ONLY=true` disables all write operations.
32+
33+
## Running Locally
34+
35+
```bash
36+
uv sync
37+
uv run python manage.py migrate
38+
uv run python manage.py runserver
39+
```
40+
41+
Your app is now available at `http://localhost:8000`.
42+
43+
## One-Click Deploy
44+
45+
Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=vercel-examples):
46+
47+
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fpython%2Fdjango-notes&project-name=django-notes&repository-name=django-notes&demo-title=Django%20Notes&demo-description=A%20simple%20note-taking%20app%20built%20with%20Django.&demo-url=https%3A%2F%2Fdjango-notes.vercel.app%2F&products=%5B%7B%22type%22%3A%22integration%22%2C%22group%22%3A%22postgres%22%7D%5D)
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import os
2+
import urllib.parse
3+
from pathlib import Path
4+
5+
BASE_DIR = Path(__file__).resolve().parent.parent
6+
7+
SECRET_KEY = os.environ.get("DJANGO_SECRET_KEY", "django-insecure-change-me-in-production")
8+
9+
DEBUG = os.environ.get("DJANGO_DEBUG") == "1"
10+
11+
ALLOWED_HOSTS = ["127.0.0.1", "localhost", ".vercel.app"]
12+
13+
READ_ONLY = os.environ.get("READ_ONLY") == "1"
14+
15+
INSTALLED_APPS = [
16+
"django.contrib.contenttypes",
17+
"django.contrib.staticfiles",
18+
"notes",
19+
]
20+
21+
MIDDLEWARE = [
22+
"django.middleware.security.SecurityMiddleware",
23+
"django.middleware.common.CommonMiddleware",
24+
"django.middleware.csrf.CsrfViewMiddleware",
25+
]
26+
27+
ROOT_URLCONF = "config.urls"
28+
29+
TEMPLATES = [
30+
{
31+
"BACKEND": "django.template.backends.django.DjangoTemplates",
32+
"DIRS": [],
33+
"APP_DIRS": True,
34+
"OPTIONS": {
35+
"context_processors": [
36+
"django.template.context_processors.request",
37+
"notes.context_processors.read_only",
38+
],
39+
},
40+
},
41+
]
42+
43+
WSGI_APPLICATION = "config.wsgi.application"
44+
45+
if os.environ.get("DATABASE_URL"):
46+
url = urllib.parse.urlparse(os.environ["DATABASE_URL"])
47+
DATABASES = {
48+
"default": {
49+
"ENGINE": "django.db.backends.postgresql",
50+
"NAME": url.path.lstrip("/"),
51+
"USER": url.username,
52+
"PASSWORD": url.password,
53+
"HOST": url.hostname,
54+
"PORT": url.port,
55+
}
56+
}
57+
else:
58+
DATABASES = {
59+
"default": {
60+
"ENGINE": "django.db.backends.sqlite3",
61+
"NAME": BASE_DIR / "db.sqlite3",
62+
}
63+
}
64+
65+
LANGUAGE_CODE = "en-us"
66+
TIME_ZONE = "UTC"
67+
USE_I18N = True
68+
USE_TZ = True
69+
70+
STATIC_ROOT = BASE_DIR / "staticfiles"
71+
STATIC_URL = "/static/"

python/django-notes/config/urls.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.urls import path, include
2+
3+
urlpatterns = [
4+
path("", include("notes.urls")),
5+
]

python/django-notes/config/wsgi.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
"""
2+
WSGI config for django-notes project.
3+
4+
It exposes the WSGI callable as a module-level variable named ``application``.
5+
6+
For more information on this file, see
7+
https://docs.djangoproject.com/en/stable/howto/deployment/wsgi/
8+
"""
9+
10+
import os
11+
12+
from django.core.wsgi import get_wsgi_application
13+
14+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
15+
16+
application = get_wsgi_application()

python/django-notes/manage.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/usr/bin/env python
2+
"""Django's command-line utility for administrative tasks."""
3+
4+
import os
5+
import sys
6+
7+
# Load .env.local if present (e.g. after running `vercel env pull`)
8+
_env_file = os.path.join(os.path.dirname(os.path.abspath(__file__)), ".env.local")
9+
if os.path.exists(_env_file):
10+
with open(_env_file) as f:
11+
for line in f:
12+
line = line.strip()
13+
if line and not line.startswith("#") and "=" in line:
14+
key, _, value = line.partition("=")
15+
os.environ.setdefault(key.strip(), value.strip().strip("\"'"))
16+
17+
18+
def main():
19+
"""Run administrative tasks."""
20+
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "config.settings")
21+
try:
22+
from django.core.management import execute_from_command_line
23+
except ImportError as exc:
24+
raise ImportError(
25+
"Couldn't import Django. Are you sure it's installed and "
26+
"available on your PYTHONPATH environment variable? Did you "
27+
"forget to activate a virtual environment?"
28+
) from exc
29+
execute_from_command_line(sys.argv)
30+
31+
32+
if __name__ == "__main__":
33+
main()

python/django-notes/notes/__init__.py

Whitespace-only changes.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
from django.conf import settings
2+
3+
4+
def read_only(request):
5+
return {"read_only": settings.READ_ONLY}

python/django-notes/notes/forms.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
from django import forms
2+
from .models import Note
3+
4+
5+
class NoteForm(forms.ModelForm):
6+
class Meta:
7+
model = Note
8+
fields = ["title", "body"]
9+
widgets = {
10+
"title": forms.TextInput(attrs={
11+
"placeholder": "Note title",
12+
"autofocus": True,
13+
}),
14+
"body": forms.Textarea(attrs={
15+
"placeholder": "Write your note here...",
16+
"rows": 8,
17+
}),
18+
}

0 commit comments

Comments
 (0)