こんにちは!Masaです。
7回目の今回は削除ボタンの実装と口座と収支の紐づけを行っていきます。
- Django初心者で簡単なWebアプリケーション作成を考えている人
- Djangoの学び直しをしている人
- Djangoの基礎を身に付けたい人
前回のおさらいと今回やること
前回の記事では月別詳細ページの作成を行いました。
実際に起動するとこのようなページになります。
今回は削除ボタンの実装と、銀行口座を収支と紐づけることが出来ようにしたいと思います。
(収入があれば口座の残高が増える、支出があれば残高が減るなど)
頑張っていきましょう💪
削除ボタンの実装
各項目の削除の流れとして、
- 削除ボタンを押す
- モーダルが表示され、最終確認をする
- モーダル内の削除ボタンを押して削除
にしたいと思います。
テンプレートに削除ボタンを配置する
最初に削除ボタンを配置します。
以下のようにテンプレートに追加しましょう。
{% extends 'money_diary/base.html' %}
{% block content %}
<h2>月次収支</h2>
<table class="table">
<thead>
<tr>
<th scope="col">当月収入</th>
<th scope="col">当月支出</th>
<th scope="col">当月収支</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ income_total }}</td>
<td>{{ expense_total }}</td>
<td>{{ balance_payment }}</td>
</tr>
</tbody>
</table>
<nav aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item">
<a class="page-link" href="{% url 'monthly_details' last_year last_month %}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
<h1>{{ year }}年{{ month }}月</h1>
<li class="page-item">
<a class="page-link" href="{% url 'monthly_details' next_year next_month %}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
</ul>
</nav>
<h2>収入</h2>
<table class="table">
<thead>
<tr>
<th scope="col">日付</th>
<th scope="col">内容</th>
<th scope="col">金額</th>
<th scope="col">金融機関</th>
<th scope="col">日付</th>
<th scope="col">メモ</th>
<th scope="col">削除</th>
</tr>
</thead>
<tbody>
{% for item in income %}
<tr>
<td>{{ item.date }}</td>
<td>{{ item.category }}</td>
<td>{{ item.date }}</td>
<td>{{ item.amount }}</td>
<td>{{ item.account }}</td>
<td>{{ item.memo }}</td>
<td><a type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop1">削除</a></td>
<!-- Modal -->
<div class="modal fade" id="staticBackdrop1" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">以下のレコードを削除しますか?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{{ item.date }}_{{ item.category }}_¥{{ item.amount }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取り消し</button>
<a type="submit" class="btn btn-primary" href="{% url 'income_delete' item.id %}">削除</a>
</div>
</div>
</div>
</div>
</tr>
{% endfor %}
</tbody>
</table>
<h2>支出</h2>
<table class="table">
<thead>
<tr>
<th scope="col">日付</th>
<th scope="col">内容</th>
<th scope="col">金額</th>
<th scope="col">金融機関</th>
<th scope="col">日付</th>
<th scope="col">メモ</th>
<th scope="col">削除</th>
</tr>
</thead>
<tbody>
{% for item in expense %}
<tr>
<td>{{ item.date }}</td>
<td>{{ item.category }}</td>
<td>{{ item.date }}</td>
<td>{{ item.amount }}</td>
<td>{{ item.account }}</td>
<td>{{ item.memo }}</td>
<td><<a type="button" class="btn btn-outline-primary" data-bs-toggle="modal" data-bs-target="#staticBackdrop2">削除</a>/td>
<!-- Modal -->
<div class="modal fade" id="staticBackdrop2" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">以下のレコードを削除しますか?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
{{ item.date }}_{{ item.category }}_¥{{ item.amount }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取り消し</button>
<a type="submit" class="btn btn-primary" href="{% url 'expense_delete' item.id %}">削除</a>
</div>
</div>
</div>
</div>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
元々作成していた収入・支出の一覧テーブルに削除ボタンとモーダルを配置しました。
モーダル内の削除ボタンのクリックで、各ビューの処理を行います。
削除処理の詳細はこの後記述しtます。
URLの作成
次にモーダル内の削除ボタンを押したときに通すパスを作成しましょう。
“money_diary/urls.py”の最後2行にパスを追加しました。
from django.urls import path
from . import views
urlpatterns = [
path('', views.IndexView.as_view(), name='index'),
path('monthly_details/', views.Monthly_DetailsView.as_view(), name='monthly_details'),
path('monthly_details/<int:year>/<int:month>', views.Monthly_DetailsView.as_view(), name='monthly_details'),
path('by_account/', views.By_AccountView.as_view(), name='by_account'),
path('assets/', views.AssetsView.as_view(), name='assets'),
path('setup/', views.SetupView.as_view(), name='setup'),
path('income_delete/<int:id>', views.Income_Delete, namne='income_delete'), #追加
path('expense_delete/<int:id>', views.Expense_Delete, namne='expense_delete'), #追加
]
ビューの作成
収入、支出の項目の削除処理を行うメソッドを追加します。
”views.py”の好きなところに追加して下さい。
def Income_Delete(self, num):
income = Income.objects.get(id=num)
income.delete()
return redirect(to='/monthly_details')
def Expense_Delete(self, num):
expense = Expense.objects.get(id=num)
expense.delete()
return redirect(to='/monthly_details')
処理内容としては
- 引数のidを使用して、データを取り出す
- 取り出したデータを削除する
という流れになります。
これで削除ボタンの基本的実装が完了です。
金融機関の紐づけ(前半)
次に金融機関の作成を行いたいと思います。
せっかく収支の入力の際に銀行口座や財布を選択する欄を作成しているので、収支登録の際に残高の増減も関連付けを行いたいと思います。
モデルの変更
まずは収支のモデルと銀行口座のモデルでリレーションシップを構成しましょう。
方法はカテゴリーの時と全く同じです。
以下のようにコードを記述します。
#収入のモデル
class Income(models.Model):
date = models.DateField(default=timezone.now) #日付
category = models.OneToOneField(IncomeCategories, on_delete=models.CASCADE) #カテゴリ
account = models.OneToOneField(Account, on_delete=models.CASCADE) #入金口座(変更)
amount = models.IntegerField() #金額
memo = models.TextField(null=True, blank=True, max_length=100) #メモ
def __str__(self):
return self.category.name + str(self.amount) #変更
#支出のモデル
class Expense(models.Model):
date = models.DateField(default=timezone.now) #日付
category = models.OneToOneField(ExpenseCategories, on_delete=models.CASCADE) #カテゴリ
account = models.OneToOneField(Account, on_delete=models.CASCADE) #出所(変更)
amount = models.IntegerField() #金額
memo = models.TextField(null=True, blank=True, max_length=100) #メモ
def __str__(self):
return self.category.name + str(self.amount) #変更
注意点として、”Account”をそれぞれのモデルより上部に配置してください!
また、銀行口座の推移をデータベースに蓄えるため、以下のモデルクラスを作成します。
これは”Account”の次に記述してください。
class AccountBalance(models.Model):
date = models.DateField(default=timezone.now)
name = models.ForeignKey(Account, on_delete=models.CASCADE)
balance = models.IntegerField()
def __str__(self):
return str(self.date) +'_' + self.name.name
記述できたらadmin.pyに登録、マイグレーションを行いましょう。
フォームの作成
次に銀行口座を登録するためのフォームを作成しましょう。
また、収入、支出を入力する際、銀行口座を選択できるように変更します。
from django import forms
from django.forms.models import ModelChoiceField
from .models import(
Income,
Expense,
IncomeCategories,
ExpenseCategories,
Account, #追加
)
#収入入力のフォーム
class IncomeForm(forms.ModelForm):
category = ModelChoiceField(queryset=IncomeCategories.objects.all())
class Meta:
model = Income
fields = '__all__'
#支出入力のフォーム
class ExpenseForm(forms.ModelForm):
category = ModelChoiceField(queryset=ExpenseCategories.objects.all())
class Meta:
model = Expense
fields = '__all__'
#金融機関登録のフォーム #追加
class AccountForm(forms.ModelForm):
class Meta:
model = Account
fields = '__all__'
これで現在収入・支出入力の口座名記入部分が選択式になっており、選択肢がない状態だと思います。
まだデータを追加していないのでOKです!
フォームの配置
次にフォームを配置しましょう。
フォームは設定画面からモーダルで登録できるようにしたいと思います。
“setup.html”に記述しましょう。
{% extends 'money_diary/base.html' %}
{% block content %}
<div class="list-group">
<button type="button" class="list-group-item list-group-item-action"data-bs-toggle="modal" data-bs-target="#account_create">口座の登録</button>
<!-- 収入のモーダル -->
<div class="modal fade" id="account_create" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="exampleModalLabel">口座の登録</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form method="post">
<div class="modal-body">
{% csrf_token %}
{{ accountform.as_p }}
</div>
<div class="modal-footer">
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取り消し</button>
<button type="submit" name="income_register_button" class="btn btn-primary">追加</button>
</div>
</form>
</div>
</div>
</div>
<button type="button" class="list-group-item list-group-item-action"></button>
<button type="button" class="list-group-item list-group-item-action"></button>
<button type="button" class="list-group-item list-group-item-action"></button>
</div>
{% endblock %}
ビューの作成
最後にビューの作成を行います。
今回の記事では口座登録までの処理を行い、次回収入・支出の入力と連携したいと思います。
“views.py”に以下のコードを記述しましょう。
from .forms import IncomeForm, ExpenseForm, AccountForm #追加
#設定画面の処理(追加)
class SetupView(View):
def get(self, request):
accountform = AccountForm()
params = {
'accountform': accountform,
}
return render(request, 'money_diary/setup.html', params)
def post(self, request):
if 'account' in request.POST:
account = Account()
accountform = AccountForm(request.POST, instance=account)
accountform.save()
return redirect(to='/setup')
これで口座の登録ができるようになりました。
まとめ
本日は削除ボタンの実装と金融機関の紐づけの前半を行いました。
次回の記事では、収入、支出の入力を行った時に銀行口座に残高が増減するような機能を作成したいと思います。
最後まで読んでいただきありがとうございます。
自己学習に役立てていただけたら嬉しく思います
またSNSやブログでシェアしていただくことや、誤植などをコメントで指摘いただけたら幸いです。
次回の記事↓
コメント