質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Q&A

解決済

2回答

1797閲覧

Djangoでユーザーがフォームに入力した数値をもとに処理を実行したい

branch

総合スコア70

Django

DjangoはPythonで書かれた、オープンソースウェブアプリケーションのフレームワークです。複雑なデータベースを扱うウェブサイトを開発する際に必要な労力を減らす為にデザインされました。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

0グッド

2クリップ

投稿2021/04/15 07:54

編集2021/04/16 06:26

Dajngo3.1にて練習がてら勤怠管理システムを作成しています.

やりたいこと

イメージ説明
上画面を従業員(=打刻者)が操作して,出勤/退勤ボタンを押すとその時刻をデータベースに登録させるという動作を実現したいのですが,formの入力値をデータベースに登録させるまでの流れが掴めない状態です.

周辺ファイルとか

base

1<!--base.html--> 2 3<!doctype html> 4<html lang="en"> 5<head> 6 <title>TimeCard</title> 7 {% block head %} 8 {% endblock head %} 9</head> 10 11<body> 12 {% block header %} 13 {% endblock header %} 14 {% block content %} 15 {% endblock content %} 16</body> 17</html>

Attendance

1<!--Attendance.html--> 2 3{% extends 'base.html' %} 4 5{% block head %} 6<script> 7 function updateClock() { 8 var now = new Date(); 9 var today = new Date(); 10 var year = today.getFullYear(); 11 var month = today.getMonth() + 1; 12 var week = today.getDay(); 13 var day = today.getDate(); 14 var hour = now.getHours(); 15 var minute = now.getMinutes(); 16 var second = now.getSeconds(); 17 var week_ja = new Array("日", "月", "火", "水", "木", "金", "土"); 18 19 if (hour < 10) hour = "0" + hour; 20 if (minute < 10) minute = "0" + minute; 21 if (second < 10) second = "0" + second; 22 document.getElementById('myClock').innerHTML 23 = year + "年" + month + "月" + day + "日 " + "(" + week_ja[week] + ")" + "<br>" + hour + ":" + minute + ":" + second; 24 } 25 function start() { 26 setInterval("updateClock();", 1000); 27 updateClock(); 28 } 29</script> 30{% endblock head %} 31 32{% block content %} 33 34<body onload="start();"> 35 <div id="myClock" align="center" style="font:bold 20pt Times New Roman;"></div> 36 <hr> 37 38 <div class="container" align="center"> 39 <form action="{% 'submit_attencanceview' %}" method="POST">{% csrf_token %} 40 {{ form.as_p }} 41 <input type="submit" value="出勤" name="arrive"> 42 <input type="submit" value="退勤" name="leave"> 43 </form> 44 </div> 45 46</body> 47{% endblock content %}

forms

1# forms.py 2from django import forms 3 4class StaffAttendanceForm(forms.Form): 5 staff_id = forms.IntegerField() 6

views

1# views.py 2from django.shortcuts import render, redirect 3from django.contrib.auth.models import User 4from .forms import StaffAttendanceForm 5 6def attendanceview(request): 7 template_name = "attendance.html" 8 context = {"form": StaffAttendanceForm()} 9 return render(request, template_name, context) 10 11def submit_attendanceview(request, pk): 12 if request.method == 'POST': 13 if "arrive" in request.POST: 14 print("just arrived" + "& id:" + str(pk)) 15 elif "leave" in request.POST: 16 print("just left" + "& id:" + str(pk)) 17

データベースとしてmodels.py内に
親会社モデル(ParentCompanyModel),
子会社モデル(ChildCompanyModel),
従業員モデル(StaffModel),
勤怠管理モデル(AttendanceModel)を作成しました.
※今回保存されている内容はadminから直接入力しました.将来的にはユーザー画面上から入力できるように実装していきます.

ParentCompanyModel

1id name 2---------- ---------- 31 Avocado Group 42 Banana Group

ChildCompanyModel

1id name parent_company_id 2---------- ------------------ ----------------- 31 Avocado Solutions 1 42 Avocado Engineering 1 53 Banana Solutions 2 64 Banana Engineering 2

StaffModel

1id name place employee_id regular_start regular_finish 2---------- ---------- ------------ ------------ ------------- -------------- 31 Ichiro Avocado Solutions 12345 8:30 17:30 42 Jiro Banana Engineering 23456 10:00 19:00

AttendanceModel

1id in_out date time correcotr arrive_correct leave_correct company_id staff_id 2---------- ---------- ---------- ---------- ---------- -------------- ------------- ---------- ---------- 31 0 2021-04-14 08:15:00 1 1 42 0 2021-04-14 09:45:00 4 2 53 1 2021-04-14 17:45:00 1 1 64 1 2021-04-14 19:15:00 4 2 7* in_outに関しては0が出勤,1が退勤です

ためしたこと

formのボタンを押したときにsubmit_attendanceviewを実行してほしいということで,attendance.htmlのformのactionの#の部分の代わりに{% 'submit_attencanceview' %}としたところ,下記のようにエラーします.

ErrorContent

1TemplateSyntaxError at /attendance/ 2Invalid block tag on line 38: ''submit_attencanceview'', expected 'endblock'. Did you forget to register or load this tag?

この場合だと,Staff idに"12345"を入力して"出勤"ボタンを押すと,

  • URL遷移せずにsubmit_attendanceviewに"12345", "出勤"を渡してDBに保存し,
  • formをキレイにして次の人がまた打刻できる状態にする

ということを実行したいです.

まとめると,

①ボタンを押すとformの内容を取得してviews.py内の特定の関数を呼び出し実行する方法
②views.py内の関数でDBに保存する方法
③URL遷移せず処理し,formをキレイにする方法
④Staff idで呼び出すのではなく,プルダウンリストから自身の名前を選択する場合のviewの実装方針
のどれかをお教えいただきたいです.(④は将来的にぶち当たる壁であろうのでついでに,,,)

不足している情報等あれば補足しますので,お申し付けください.
(Djangoは周辺ファイルがおおくて状況を伝えにくいですね,,,)

どれか一つでも大変助かりますので,ご回答の程,どうぞよろしくお願いいたします.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

質問内容が長大なので具体的な実装について提示することはできませんが、こちらの記事はどうでしょう。
Djangoで、ログイン・ログアウトの履歴を管理する

出勤記録っていうのはつまり、ログイン・ログアウト機能と本質的には同じですよね。
このように似たような機能のサンプルコードをそのままコピーして、カスタマイズするのがアプリの構成的にも安全である気がします。

投稿2021/04/23 13:04

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

branch

2021/04/27 23:50

ありがとうございます. 残念ながらログイン・ログアウト機能とはまた異なるもので,今回のモデル設計の場合はChildCompanyModelにUserModelを継承させています. また,お陰様で本件は自己解決いたしました.また機会があればよろしくお願いします.
guest

0

自己解決

解決順に記載します.
####②views.py内の関数でDBに保存する方法
そもそもforms.pyを利用しておきながらviews.pyからDB操作するのが非効率的でした.
views.attendanceviewからformを呼び出し,.save()メソッドで保存するとDBに自動保存されます.(save(commit=False)で敢えて保留させることも可能)

####③URL遷移せず処理し,formをキレイにする方法
attendance.htmlの出退勤ボタンにPOST属性を持たせて,遷移先を再度attendance.htmlに指定します.この時,views.attendanceviewの中でPOSTメソッドで呼び出したときにだけレコードを処理するようにすると期待動作が実現できました.

attendance

1(一部抜粋) 2 3<body onload="start();"> 4 <div id="myClock" align="center" style="font:bold 20pt Times New Roman;"></div> 5 <hr> 6 7 <div class="container" align="center"> 8 <form action="{% url 'attendance' %}" method="POST">{% csrf_token %} 9 {{ form.as_p }} 10 <input type="submit" value="出勤" id="arrive" name="arrive"> 11 <input type="submit" value="退勤" id="leave" name="leave"> 12 </form> 13 </div> 14 15</body>

####④Staff idで呼び出すのではなく,プルダウンリストから自身の名前を選択する場合のviewの実装方針
forms.pyModelChoiceFieldを使えば実現できました.
####①ボタンを押すとformの内容を取得してviews.py内の特定の関数を呼び出し実行する方法
今回は使用しませんでしたが,カスタムテンプレートタグで実現可能そうです.

以下,forms.py及びviews.py抜粋

forms

1class StaffChoiceField(forms.ModelChoiceField): 2 def label_from_instance(self, staff): 3 return f"{staff.name}" 4 5class StaffAttendanceForm(forms.Form): 6 class Meta: 7 model = AttendanceModel 8 fields = ['staff', 'company', 'work_style', 'in_out', 'datetime'] 9 10 staff = StaffChoiceField( 11 queryset= StaffModel.objects.all(), 12 empty_label= "choose...", 13 )

views

1def attendanceview(request): 2 if request.method == 'POST': 3 form = StaffAttendanceForm(request.POST or None) 4 5 if form.is_valid(): 6 form.save(commit=False) 7 8 if "arrive" in request.POST: # 出勤時 9 form.in_out = 0 10 elif "leave" in request.POST: # 退勤時 11 form.in_out = 1 12 form.datetime = datetime.datetime.now() 13 form.save() 14 15 template_name = "attendance.html" 16 context = {"form": StaffAttendanceForm()} 17 return render(request, template_name, context)

投稿2021/04/28 00:02

branch

総合スコア70

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問