Djangoでフォームの入力欄の追加をする方法(メモ)
DjangoのFormsetを使うときにフォームの追加をする方法をまとめておきます。メモなのでだいぶ雑です。
バージョンは3.2.20です。
①Djangoのみでやる
こちらのサイトを参考にやっていたのですが、グローバル変数を使っており実用向きではありません。グローバル変数を使わずに書いてみます。
models.py
from django.db import models class Group(models.Model): name = models.CharField(max_length=100) class Member(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) name = models.CharField(max_length=100) email = models.EmailField(max_length=255)
views.py
from django.views import generic from django import forms from django.shortcuts import render from .models import Group, Member class MemberView(generic.FormView): template_name = 'app/member.html' def get_success_url(self): return reverse_lazy('app:member', kwargs={'pk': self.kwargs['pk']}) def get_form(self): group = Group.objects.get(pk=self.kwargs['pk']) MemberFormset = forms.modelformset_factory( Member, fields=["name", "email",], extra=3, max_num=100, can_delete=True, ) queryset = Member.objects.filter(group=group) if self.request.method == 'POST': formset = MemberFormset(**self.get_form_kwargs()) else: formset = MemberFormset(queryset=queryset) return formset def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) return context def get_form_kwargs(self): kwargs = super.get_form_kwargs() if self.request.POST and 'add' in self.request.POST: kwargs['data'] = self.request.POST.copy() kwargs['data']['form-TOTAL_FORMS'] = int(kwargs['data']['form-TOTAL_FORMS']) + 1 return kwargs def post(self, request, *args, **kwargs): if 'add' in request.POST: context = self.get_context_data(**kwargs) return render(request, self.template_name, context) return super().post(request, *args, **kwargs) def form_valid(self, form): if 'submit' in self.request.POST: data = form.cleaned_data group = Group.objects.get(pk=self.kwargs['pk']) for member_parameter in data: if member_parameter: try: member = member_parameter['id'] member.name = member_parameter['name'] member.email = member_parameter['email'] member.save() except: Member.objects.create( group=group, name=member_parameter['name'], email=member_parameter['email'], ) return super().form_valid(form)
テンプレートには {{ form }}
で描画できます。
②JavaScriptを使ってやる
こちらのサイトを参考にやりました。JavaScriptはこちらのものを一部変更して、更新処理などをできるようにしました。
models.py(①と同じです)
from django.db import models class Group(models.Model): name = models.CharField(max_length=100) class Member(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) name = models.CharField(max_length=100) email = models.EmailField(max_length=255)
forms.py
from .models import Group, Member from django import forms MemberFormset = forms.inlineformset_factory( Group, Member, fields=('name', 'email'), extra=0, can_delete=True )
views.py
from .forms import MemberFormset from .models import Group, Member from django.shortcuts import redirect, render, get_object_or_404 def member(request, pk): group = get_object_or_404(Group, pk=pk) formset = MemberFormset(request.POST or None, instance=group) if request.method == 'POST' and formset.is_valid(): formset.save() return redirect('app:member', pk=group.pk) context = { 'formset': formset, 'group': group, } return render(request, 'app/member.html', context)
$(function() { // フォームの追加をする部分は同じなので省略します $('#form').submit(function() { const text = $('.text'); $('[name=form-TOTAL_FORMS]').val(text.length); // それぞれの入力欄の__prefix__をindexで置換する text.each(function(index, element){ originalHtml = $(element).html(); replacedHtml = $(element).html().replace(/__prefix__/g, index); // empty_formのみ置換の処理を行う if (originalHtml !== replacedHtml) { // valueが消えるのですべての項目に対して保存 value_name = $(element).find("#id_form-__prefix__-name").val(); value_email = $(element).find("#id_form-__prefix__-email").val(); is_delete = $(element).find("#id_form-__prefix__-DELETE").prop('checked'); $(element).html(replacedHtml); $(element).find("#id_form-" + index + "-name").val(value_name); $(element).find("#id_form-" + index + "-email").val(value_email); $(element).find("#id_form-" + index + "-DELETE").prop('checked', is_delete); } }); }); });
テンプレートにはすでに入力されている(されていない場合は空)formsetと、empty_formを1つ書いておきます。
ビューの実装はこちらも参考にしました。
2023/10/26追記: JavaScriptも一部変える必要があったので更新しました。
11月のこんにちは
2023/02/06 11月の記事の下書きが残っていたので公開しておきます。
10月前半
なんやかんやしていたら授業に全然出られませんでした。記憶が全くありません。
10月後半
なんやかんやしていたら授業に全然出られませんでした。記憶があまりありません。
残っている記憶を紹介します。
10代終了…… pic.twitter.com/0HdjCPh4KZ
— るーと (@nrRoute) 2022年10月19日
誕生日でした。ついに20歳になってしまいました。できるだけ濃い20代を過ごしたいものです。
#ラーメン大戦争京都河原町店 pic.twitter.com/d5iu5o102S
— るーと (@nrRoute) 2022年10月21日
できたばかりのラーメン屋に行きました。見た目のインパクトがすごいです。もはやチャーシューが器になっています(いいえ)。
良かった曲、アルバム等
Spotifyと復縁しました。
FPMの2ndを中古CD屋で購入しました。*********recordsのアルバムはだいたいサブスクにないので中古CD屋を渡り歩いて見つけるしかない……わけではないですが、僕はそうしています。
2月のこんにちは
11月の終わりごろまで壊滅的な生活を送っており、1度も授業に出ない週もありました。12月以降は健常者の生活リズムを取り戻そうと努力はしたものの、完全には取り戻せないままテストを迎えて壊滅的な結果を残してしまうことに……来期はどうなるのでしょうか。そもそも希望通りのコースに配属されるかどうかが怪しいです。
音楽
すごくいいです。ミュージックマガジン誌の2022年のベストアルバムにも選出されていました。
だんだん音楽を探すために張っているアンテナが歪になってきました。
よかったもの2022
更新をサボりすぎて年末になっていました。すいません。今年聴いてナイスだと思った曲とアルバム(リリース年は限定しません)を書き残しておきます。順番は適当です。カッコ内はリリース年のつもりですが、間違っているかもしれません。余裕があればサブスクかYouTubeのリンクも載せます。
アルバム
- tofubeats - lost decade (2013)
- Cornelius - Mellow Waves (2017)
- CAPSULE - phony phonic (2003)
- betcover!! - 時間 (2021)
- TEMPLIME & 星宮とと - skycave (2022)
- 大貫妙子 - SUNSHOWER (1977)
- 佐野元春 - 月と専制君主 (2011)
- Plus-Tech Squeeze Box - catooom! (2004)
- Crackazat - Evergreen (2022)
- Limre - ライマー (2022)
- DOMi & JD BECK - NOT TiGHT (2022)
- in the blue shirt - Park with a Pond (2022)
- 和泉宏隆 & フレンズ - Unforgotten Saga (2022)
- ラブリーサマーちゃん - THE THIRD SUMMER OF LOVE (2020)
- FPM - THE FANTASTIC PLASTIC MACHINE (1997)
- The 1975 - Being Funny In A Foreign Language (2022)
- SOLEIL - LOLIPOP SIXTEEN (2019)
- 藤井隆 - Music Restaurant Royal Host (2022)
- KIRINJI - ペイパードライヴァーズミュージック (1998)
- RYUTist - (エン)(2022)
- Louis Cole - Quality Over Opinion (2022)
- Ink Waruntorn - INK (2022)
- betcover!! - 卵 (2022)
曲
- 星宮とと+TEMPLIME - SUICHU (Tomggg Remix) (2022)
- 稲葉曇 - ラグトレイン (OLDUCT Remix) (2022)
- AOTQ & 夏目間風 - スランプ (2022)
- 島村卯月、本田未央、渋谷凛、神谷奈緒、北条加蓮 - STORY (2016)
- 長瀬麻奈 - Precious (2021)
- Mitsukiyo - Bunny Bunny Carrot Carrot (2022)
- 花澤香菜 - magical mode (2021)
- TINGS - TOKYO WATASHI COLLECTION (2022)
- 松田聖子 - SWEET MEMORIES (1983)
- 黛冬優子 - SOS (2021)
- 潟女DIY部!! - どきどきアイデアをよろしく! (2022)
- 北白川たまこ - ドラマチックマーケットライド (2013)
- どーなっつ◎くいんてっと - プラチナジェット (2015)
- 中川亜紀子 - 夢の都 TOKYO LIFE (2002)
- KIRINJI - Drifter (2001)
- tricot - おちゃんせんすぅす (2013)
終わりに
今年もたくさん音楽を聴けました。来年も聴きます。
10月のこんにちは(上)
10月です。授業が始まってしまいました。夏休み後半で生活リズムが完全に崩壊してしまい、出席へのモチベーションが皆無です。実際2コマ出られませんでした。
9月後半 (夏休み終了まで)
引き続き実家でスプラトゥーン3やっていました。全然勝てませんでした。京都に帰ってからは、Webアプリ開発らしきことをしていたりしました。開発は結構楽しいです。あと、響け!ユーフォニアム(1期、2期)とリズと青い鳥を見ました。このシリーズは以前から気になっていたけど見るのが怖くて見ていなかったのですが、ある日突然「今見るしかない!!!」という気持ちになったので見ました。感想としては、本当に見てよかったです。できれば高校入学時ぐらいに見ておきたかったです。また、猫物語 (黒、白)と傾物語を見ました。忍野忍さんが可愛いです。
後期の授業開始日前日には日本橋のe-イヤホンに行きました。いろいろなイヤホンを試聴しましたが、モニターイヤホンのバランスがすごく良い感じでした。今回は何も買いませんでしたが、今度行った時にもう一度試聴し直して良いものがあれば買おうと思います。
履修登録についてですが、抽選科目は9個申し込んで4個当たっていました。
良かった曲、アルバム等
FPMの1stが日本橋の中古CDショップにあったので買いました。ハウスとボサノヴァを感じられて良いです。
アニメを見たので入れました。90年代ポップス成分を摂取できてよいです。
こちらもアニメを見たので。苦い記憶が蘇ってきます。アニメを見たことで少しだけ好きになれました。
まとめ
ちゃんと授業に出れるのでしょうか。出られないかもしれません。
9月のこんにちは(下)
遅刻です。もう19日になってしまいました。
9月前半
京都にいました。時間があったので進撃の巨人を勢いに任せて2日で全巻読みました。全然わかりませんでした。もう一回読もうと思います。ただ一気に読んでしまうぐらいに面白い作品でした。そもそも漫画を読むのはかなり久しぶりでしたが、楽しく読めたと思います。
競プロはモチベーションがなさすぎて全然やっていません。逆に開発に対するやる気が結構あったのでそういう感じのことをしていたのですが、これを書いている今はスプラトゥーン3以外のモチベーションが消えています。スプラトゥーン3は全然勝てないですがリリース直後特有の勢いに乗ってやっています。楽しいです。
良かった曲、アルバム等
12日にSpotifyの無料トライアル期間が終わり、それ以降の支払い手段がなかったので解約してしまいました。だからといって音楽に出会う機会が今より少なくなるということはないのでここのコーナーにはさほど影響はない(はず)です。そもそもTwitterとかYouTubeでたまたま出会った曲を何度も聴きたいときとかにサブスクを使うという認識でやっているので…。サブスクはクレジットカードを作ってからもう一度入ろうと思います。
響き方がとてもよいです。
追悼アルバムです。最後のトラックにご本人が吹奏楽版の宝島の演奏に参加しているのが収録されているのですが、聞いていて不思議な感覚になりました。
まとめ
そろそろ履修登録ですね。今期は抽選全落ち回避を願っています。
9月のこんにちは(上)
9月です。夏休み折り返しですね。大学生は気楽です。
8月後半
化物語と偽物語を見ました。どのキャラもかわいいですね。歌の歌詞の意味もわかってよかったです。すべての曲を実質神前暁さん一人で作っているのに、全然ワンパターンさがないというか記名性が薄いというかで、職人技だな……という気持ちになりました。下旬には香川に行ってうどんを食べたり現代アートを見たりしました。12年ぶりに直島に上陸してきました。
さて、1回前期の成績ですが、A×4、B×8、D×1、F×1で28単位、GPAは3でした。
近況: 計算機科学概論を落としました
— るーと (@nrRoute) 2022年8月28日
計算機科学概論を落としたのは不本意でした。どうしてなのでしょうか。理解ができません。
良かった曲、アルバム等
下のツイートがTwitterのタイムラインに流れてきたので見てみたらハマりました。曲のタイトルがオランダ語なのでオランダ人のトラックメイカーなのでしょうか。ドラムンっぽい感じではありますが、Google翻訳の音声などインターネットの要素も盛り込まれていて良いです。
Here is the official teaser of the new album "dansmusiek" by gladde paling pic.twitter.com/yXQnYNGxMk
— 3D gif dubstep (@3Dgifdubstep) 2022年8月22日
これもすごくよかったです。穏やかな気持ちになれました。
2003~2006年あたりのCAPSULEっぽい雰囲気がありながら、それに加えて少し湿り気もあって良いです。
アニメを見たので。サビ前のベースが最高です。神前暁さんの曲は一貫してメロディーに親しみやすさがある気がします。
最近メインストリームの邦楽ロックをもう一度聞きたくなってきましたが、なかなかきっかけになる一曲が無いです。
まとめ
そろそろ京都に戻ろうかなと思っています。