回答ではありません
とりあえず、djagoで返したHTMLからjQueryのajaxを使ってREST APIっぽくアクセスし、その結果をコンソールに出力する簡易コード環境を作成するスクリプトを書いてみました。本来Django REST frameworkとか使うべきなんだろうけど、原始的なのが良さそうだったので、参考までにということです。
環境構築スクリプト
python
1import os
2import venv
3import subprocess
4ENV = 'env'
5if os.name == 'posix':
6 BIN = 'bin'
7else:
8 BIN = 'Scripts'
9builder = venv.EnvBuilder(with_pip=True)
10builder.create(ENV)
11cwd = os.getcwd()
12python = os.path.join(cwd, ENV, BIN, 'python')
13os.environ['VIRTUAL_ENV'] = os.path.join(cwd, ENV)
14os.environ['PATH'] = os.path.join(cwd, ENV, BIN) + os.pathsep + os.environ['PATH']
15p = subprocess.run([python, '-m', 'pip', 'install', '--upgrade', 'pip', 'setuptools'])
16p = subprocess.run([python, '-m', 'pip', 'install', 'django==4.1.7', 'whatthepatch==1.0.4'])
17with open('generated.py', 'wt', encoding='utf8') as f:
18 f.write("""\
19import subprocess
20import os
21p = subprocess.run('django-admin startproject mysite', shell=True)
22os.chdir('mysite')
23p = subprocess.run('python manage.py startapp myapp', shell=True)
24p = subprocess.run('python ../patch.py ../patch.diff', shell=True)
25""")
26with open('patch.diff', 'wt', encoding='utf8') as f:
27 f.write("""\
28diff --git a/myapp/templates/myapp/index.html b/myapp/templates/myapp/index.html
29new file mode 100644
30index 0000000..e0a8b77
31--- /dev/null
32+++ b/myapp/templates/myapp/index.html
33@@ -0,0 +1,22 @@
34+{% csrf_token %}
35+<button id="start_ajax">ここ</button>
36+<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
37+<script>
38+$('#start_ajax').on('click', (ev)=>{
39+ $.ajax({
40+ url: '{% url "api" %}',
41+ type: "POST",
42+ headers: {
43+ 'X-CSRFToken': $('input[name="csrfmiddlewaretoken"]').attr('value')
44+ },
45+ data: {
46+ 'id': 'hoge',
47+ 'new_text': 'fuga',
48+ },
49+ dataType: "json",
50+ }).done((data) => {
51+ console.log(data);
52+ });
53+});
54+</script>
55+
56diff --git a/myapp/urls.py b/myapp/urls.py
57new file mode 100644
58index 0000000..70c2b6b
59--- /dev/null
60+++ b/myapp/urls.py
61@@ -0,0 +1,7 @@
62+from django.urls import path
63+from . import views
64+
65+urlpatterns = [
66+ path('', views.index, name='index'),
67+ path('api/', views.api, name='api'),
68+]
69diff --git a/myapp/views.py b/myapp/views.py
70index 91ea44a..4ad8b95 100644
71--- a/myapp/views.py
72+++ b/myapp/views.py
73@@ -1,3 +1,8 @@
74 from django.shortcuts import render
75+from django.http import JsonResponse
76
77-# Create your views here.
78+def index(request):
79+ return render(request, 'myapp/index.html', {})
80+
81+def api(request):
82+ return JsonResponse({'newid': request.POST['id'] + '1', 'text': request.POST['new_text'] + '2'})
83diff --git a/mysite/settings.py b/mysite/settings.py
84index 5ebda72..4c6fdc7 100644
85--- a/mysite/settings.py
86+++ b/mysite/settings.py
87@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
88 # Application definition
89
90 INSTALLED_APPS = [
91+ 'myapp.apps.MyappConfig',
92 'django.contrib.admin',
93 'django.contrib.auth',
94 'django.contrib.contenttypes',
95@@ -103,9 +104,9 @@ AUTH_PASSWORD_VALIDATORS = [
96 # Internationalization
97 # https://docs.djangoproject.com/en/4.1/topics/i18n/
98
99-LANGUAGE_CODE = 'en-us'
100+LANGUAGE_CODE = 'ja'
101
102-TIME_ZONE = 'UTC'
103+TIME_ZONE = 'Asia/Tokyo'
104
105 USE_I18N = True
106
107diff --git a/mysite/urls.py b/mysite/urls.py
108index 8bc0cd4..d2fd81c 100644
109--- a/mysite/urls.py
110+++ b/mysite/urls.py
111@@ -14,8 +14,9 @@ Including another URLconf
112 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
113 \"\"\"
114 from django.contrib import admin
115-from django.urls import path
116+from django.urls import include, path
117
118 urlpatterns = [
119+ path('myapp/', include('myapp.urls')),
120 path('admin/', admin.site.urls),
121 ]
122""")
123with open('patch.py', 'wt', encoding='utf8') as f:
124 f.write("""\
125import whatthepatch, os, sys
126with open(sys.argv[1], 'rt', encoding='utf8') as fp:
127 for diff in whatthepatch.parse_patch(fp):
128 header = diff.header
129 if header.new_path == '/dev/null':
130 os.remove(header.old_path)
131 else:
132 if header.old_path == '/dev/null':
133 old = []
134 else:
135 with open(header.old_path, 'rt', encoding='utf8') as fo:
136 old = [line.rstrip(os.linesep) for line in fo]
137 new = whatthepatch.apply_diff(diff, old)
138 try:
139 os.makedirs(os.path.dirname(header.new_path))
140 except FileExistsError:
141 pass
142 with open(header.new_path, 'wt', encoding='utf8') as fn:
143 for line in new:
144 print(line, file=fn)
145""")
146p = subprocess.run([python, 'generated.py'])
環境構築スクリプトの使い方
- 上記ファイルをcreate_env.pyという名前で作成
- tmpディレクトリを作成
- tmpディレクトリに移動
- create_env.pyを実行
Windows(コマンドプロンプト)の場合
cmd
1C:\...\>cd create_env.pyを作ったフォルダ
2C:\...\>mkdir tmp
3C:\...\>cd tmp
4C:\...\>python ..\create_env.py
Unixライク系(bash)の場合
Ubuntuの場合は、venvを使えるようにpython3-venvパッケージのインストールが必要です(入れてない場合)。
bash
1$ cd create_env.pyを作ったフォルダ
2$ mkdir tmp
3$ cd tmp
4$ python ../create_env.py
5
6以上で環境構築完了です。
7
8## 構築環境への入り方
9上記スクリプトは他のpython環境に影響を与えないため、`venv`を使った仮想環境(といってもVMとかじゃない)を作っています。環境を使うためには、まずvenvでその環境に入る必要があります。
10
11### Windows(コマンドプロンプト)の場合
12```cmd
13C:\...\>cd さっき作ったtmpディレクトリ
14C:\...\>.\env\Scripts\activate
15(env)C:\...\>
16...(作業が終わったら)...
17(env)C:\...\>deactivate
18C:\...\>
Unixライク系(bash)の場合
bash
1$ cd さっき作ったtmpディレクトリ
2$ ./env/bin/activate
3(env)$
4...(作業が終わったら)...
5(env)$ deactivate
6$
djangoの起動
これは説明するまでもないと思いますが、mysite
プロジェクトのディレクトリに移動後、python manage.py runserver
でローカルの8000ポートに起動します。
ブラウザから接続
http://localhost:8000/myapp
を開き、Ctrl+Shift+Iとかで開発者ツールの画面を開きます。ネットワーク画面でhttpプロトコルの内容を確認しながら、「ここ」ボタンを押すと、ajaxのリクエストが出てレスポンスが返り、コンソールにjsonが表示されているのがわかります。
djangoのviewとtemplateの解説
tmp/mysite/myapp/views.py
python
1from django.shortcuts import render
2from django.http import JsonResponse
3
4def index(request):
5 return render(request, 'myapp/index.html', {})
6
7def api(request):
8 return JsonResponse({'newid': request.POST['id'] + '1', 'text': request.POST['new_text'] + '2'})
index()
がhttp://localhost:8000/myapp/
の受け口で、テンプレートを返しています。
api()
がhttp://localhost:8000/myapp/api/
の受け口`で、ajaxでもらったデータに1と2を付けてjsonで返しています。この部分はDjango REST frameworkでいいかもというところです。
tmp/mysite/myapp/template/myapp/index.html
html
1{% csrf_token %}
2<button id="start_ajax">ここ</button>
3<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
4<script>
5$('#start_ajax').on('click', (ev)=>{
6 $.ajax({
7 url: '{% url "api" %}',
8 type: "POST",
9 headers: {
10 'X-CSRFToken': $('input[name="csrfmiddlewaretoken"]').attr('value')
11 },
12 data: {
13 'id': 'hoge',
14 'new_text': 'fuga',
15 },
16 dataType: "json",
17 }).done((data) => {
18 console.log(data);
19 });
20});
21</script>
ボタンを押されたらajaxを実行してるだけです。jsonが返ってきたらコンソールに吐いています。一点面倒なのはdjangoが生成してくれるCSRFトークンのajaxでの送信です。
https://docs.djangoproject.com/en/4.1/howto/csrf/
を参考に送ればOKです。