原因
そもそもフォームデータの取得方法がおかしい
https://docs.djangoproject.com/ja/5.0/ref/forms/api/
対策
views.py
python
1from django.shortcuts import render
2from . forms import PyForm
3
4def choices(request):
5 template = 'choices.html'
6 context = {
7 'title': 'mul_choice', #パス
8 'goto': 'mul_choices', #name
9 'message': None,
10 'form': PyForm(),
11 }
12
13 if request.method == "POST":
14 form = PyForm(request.POST)
15 if form.is_valid():
16 selected = form.cleaned_data['multi_choice']
17 context['message'] = '食べたものは: '+','.join(selected)
18 context['form'] = form
19
20 return render(request, template, context)
環境構築
私が試した環境を再現するためのものです。
django系のコードは再現コードがないと同じ話が出来ない場合が多いので。
venv下に実行環境を構築するpythonスクリプトです。ubuntuの場合事前にpython3-venvパッケージが必要です。
スクリプトを空のディレクトリに例えばcreate_env.pyという名前で保存し、python3 create_env.py
(windowsの場合はpython)すると構築されます。
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==5.0.2', 'whatthepatch==1.0.5'])
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/forms.py b/myapp/forms.py
29new file mode 100644
30index 0000000..2784dd8
31--- /dev/null
32+++ b/myapp/forms.py
33@@ -0,0 +1,15 @@
34+from django import forms
35+
36+class PyForm(forms.Form):
37+ sc = [
38+ ('肉', 'にく'),
39+ ('魚', 'さかな'),
40+ ('米', 'ごはん'),
41+ ('野菜', 'やさい'),
42+ ('汁物', 'しるもの'),
43+ ('漬物', 'つけもの'),
44+ ]
45+ multi_choice=forms.MultipleChoiceField(label='食べたもの複数選択可', choices=sc, \\
46+ widget=forms.SelectMultiple(attrs={
47+ 'size':6,'class':'form-select'
48+ }))
49diff --git a/myapp/templates/choices.html b/myapp/templates/choices.html
50new file mode 100644
51index 0000000..2c8026c
52--- /dev/null
53+++ b/myapp/templates/choices.html
54@@ -0,0 +1,6 @@
55+<form method="post">
56+ {% csrf_token %}
57+ {{ form }}
58+ <div>{{ message }}</div>
59+ <input type="submit" value="Submit">
60+</form>
61diff --git a/myapp/urls.py b/myapp/urls.py
62new file mode 100644
63index 0000000..def718a
64--- /dev/null
65+++ b/myapp/urls.py
66@@ -0,0 +1,7 @@
67+from django.urls import path
68+from . import views
69+
70+urlpatterns = [
71+ path('', views.choices, name='choices'),
72+]
73+
74diff --git a/myapp/views.py b/myapp/views.py
75index 91ea44a..f61d001 100644
76--- a/myapp/views.py
77+++ b/myapp/views.py
78@@ -1,3 +1,20 @@
79 from django.shortcuts import render
80+from . forms import PyForm
81
82-# Create your views here.
83+def choices(request):
84+ template = 'choices.html'
85+ context = {
86+ 'title': 'mul_choice', #パス
87+ 'goto': 'mul_choices', #name
88+ 'message': None,
89+ 'form': PyForm(),
90+ }
91+
92+ if request.method == "POST":
93+ form = PyForm(request.POST)
94+ if form.is_valid():
95+ selected = form.cleaned_data['multi_choice']
96+ context['message'] = '食べたものは: '+','.join(selected)
97+ context['form'] = form
98+
99+ return render(request, template, context)
100diff --git a/mysite/settings.py b/mysite/settings.py
101index 2f5eb34..addc95d 100644
102--- a/mysite/settings.py
103+++ b/mysite/settings.py
104@@ -31,6 +31,7 @@ ALLOWED_HOSTS = []
105 # Application definition
106
107 INSTALLED_APPS = [
108+ 'myapp.apps.MyappConfig',
109 'django.contrib.admin',
110 'django.contrib.auth',
111 'django.contrib.contenttypes',
112diff --git a/mysite/urls.py b/mysite/urls.py
113index dedacdb..687084f 100644
114--- a/mysite/urls.py
115+++ b/mysite/urls.py
116@@ -15,8 +15,9 @@ Including another URLconf
117 2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
118 \"\"\"
119 from django.contrib import admin
120-from django.urls import path
121+from django.urls import include, path
122
123 urlpatterns = [
124+ path('myapp/', include('myapp.urls')),
125 path('admin/', admin.site.urls),
126 ]
127""")
128with open('patch.py', 'wt', encoding='utf8') as f:
129 f.write("""\
130import whatthepatch, os, sys
131with open(sys.argv[1], 'rt', encoding='utf8') as fp:
132 for diff in whatthepatch.parse_patch(fp):
133 header = diff.header
134 if header.new_path == '/dev/null':
135 os.remove(header.old_path)
136 else:
137 if header.old_path == '/dev/null':
138 old = []
139 else:
140 with open(header.old_path, 'rt', encoding='utf8') as fo:
141 old = [line.rstrip(os.linesep) for line in fo]
142 new = whatthepatch.apply_diff(diff, old)
143 try:
144 dirpath = os.path.dirname(header.new_path)
145 if dirpath != "":
146 os.makedirs(dirpath)
147 except FileExistsError:
148 pass
149 with open(header.new_path, 'wt', encoding='utf8') as fn:
150 for line in new:
151 print(line, file=fn)
152""")
153p = subprocess.run([python, 'generated.py'])
使い方
bash
1$ . env/bin/activate # windowsの場合は.\env\Scripts\activate
2$ cd mysite
3$ python manage.py runserver
4...
5^C
6$ deactivate
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2024/02/17 13:28
退会済みユーザー
2024/02/17 13:41
退会済みユーザー
2024/02/17 13:43
退会済みユーザー
2024/02/17 14:27
2024/02/18 03:11