-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathdjango_demo.py
More file actions
159 lines (131 loc) · 5.17 KB
/
Copy pathdjango_demo.py
File metadata and controls
159 lines (131 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
"""
django_demo.py — Django inside LumiView via WSGI.
Shows:
- A Django app running on ``lumiview://`` (zero-config, no HTTP server)
- URL routing + view functions + the Django template engine
- HTML form POST handling and JSON API endpoints
- Using ``source=WSGI(django_app)`` with ``Window.create``
No ``runserver``, no port, no ``pip install`` beyond ``lumiview`` + ``django``.
The browser talks directly to Django via the ``lumiview://`` custom protocol.
Run:
pip install django
python examples/django_demo.py
"""
import json
import platform
from django import get_version
from django.conf import settings
from django.core.wsgi import get_wsgi_application
from django.http import HttpResponse, JsonResponse
from django.template import Context, Template
from django.urls import path
from lumiview import App, Window, WindowOptions
from lumiview.serve import WSGI
# ── Django app (single-file, no settings.py / urls.py needed) ──────────────
settings.configure(
DEBUG=True,
SECRET_KEY="lumiview-django-demo",
ALLOWED_HOSTS=["lumiview"],
ROOT_URLCONF=__name__,
INSTALLED_APPS=[],
# CsrfViewMiddleware is omitted on purpose: the lumiview:// protocol is
# not reachable from external browsers, so the cross-site attack surface
# is closed by design. Keep it if you load remote content into the WebView.
MIDDLEWARE=[
"django.middleware.security.SecurityMiddleware",
"django.middleware.common.CommonMiddleware",
],
DEFAULT_AUTO_FIELD="django.db.models.BigAutoField",
USE_TZ=True,
LANGUAGE_CODE="zh-hans",
)
django.setup()
INDEX_TEMPLATE = """<!doctype html>
<html>
<head><meta charset="utf-8"><title>Django + LumiView</title></head>
<body style="font-family:sans-serif;max-width:640px;margin:2rem auto;">
<h2>LumiView + Django</h2>
<p>This page is rendered by the <strong>Django template engine</strong> and served
through the <code>lumiview://</code> custom protocol — no runserver, no port.
Django version <strong>{{ django_version }}</strong> on Python {{ python_version }}.</p>
<h3>POST form</h3>
<form method="post" action="/">
<input name="message" placeholder="Type a message…" style="width:70%">
<button type="submit">Submit</button>
</form>
{% if last_message %}<p><strong>Last message:</strong> {{ last_message }}</p>{% endif %}
<h3>GET /api/info</h3>
<button onclick="callInfo()">Load framework info</button>
<pre id="info-result"></pre>
<h3>POST /api/echo</h3>
<textarea id="echo-input" rows="3" style="width:100%">{"msg":"hello django"}</textarea>
<br><button onclick="callEcho()">POST /api/echo</button>
<pre id="echo-result"></pre>
<script>
async function callInfo() {
const r = await fetch('/api/info');
document.getElementById('info-result').textContent = JSON.stringify(await r.json(), null, 2);
}
async function callEcho() {
const body = document.getElementById('echo-input').value;
const r = await fetch('/api/echo', { method: 'POST', body });
document.getElementById('echo-result').textContent = JSON.stringify(await r.json(), null, 2);
}
</script>
</body>
</html>"""
def index(request):
"""Render the main page; accept form POSTs."""
last_message = ""
if request.method == "POST":
last_message = request.POST.get("message", "")
html = Template(INDEX_TEMPLATE).render(Context({
"django_version": get_version(),
"python_version": platform.python_version(),
"last_message": last_message,
}))
return HttpResponse(html)
def api_info(request):
"""A simple JSON endpoint — note the ``lumiview://`` scheme."""
return JsonResponse({
"framework": "Django",
"django_version": get_version(),
"python_version": platform.python_version(),
"protocol": request.scheme,
})
def api_echo(request):
"""Echo a JSON body back, with request metadata."""
if request.method != "POST":
return JsonResponse({"error": "POST only"}, status=405)
try:
data = json.loads(request.body or b"{}")
except json.JSONDecodeError:
return JsonResponse({"error": "invalid JSON"}, status=400)
return JsonResponse({
"method": request.method,
"path": request.path,
"received": data,
"echo": data.get("msg", ""),
})
# URLconf lives in this module too (ROOT_URLCONF = __name__).
urlpatterns = [
path("", index),
path("api/info", api_info),
path("api/echo", api_echo),
]
# A standard Django WSGI application — fully compatible with the WSGI adapter.
django_app = get_wsgi_application()
# ── LumiView app ───────────────────────────────────────────────────────────
app = App(name="DjangoDemo")
async def main():
await Window.create(WindowOptions(
title="Django + LumiView",
source=WSGI(django_app),
width=760,
height=640,
devtools=True,
))
print("Django app running at lumiview://app/")
print("Open DevTools → Network tab to see requests flowing through the custom protocol.")
if __name__ == "__main__":
app.run(main)