こんにちは!Masaです。
6回目の今回は「月別詳細ページ」の作成を行っていきます
前回の記事↓
- Django初心者で簡単なWebアプリケーション作成を考えている人
- Djangoの学び直しをしている人
- Djangoの基礎を身に付けたい人
前回のおさらいと今回やること
前回の記事では、フォームのモーダル化とフォームに選択形式を適用させました。
今回の記事では、4回目に作成した別ページを使用して月別詳細ページを作成したいと思います。
月別詳細ページとは指定した月の収支の合計や収支の詳細がわかるページのことです。
各収入や支出の編集も行えるようにしたいですね。
今回は作成しませんが、カレンダーで表示できるようにするのもいいと思うので後日やってみたいと思います。
月別詳細ページの作成
ビューの作成(GET時)
まずGET時のビューの処理を作成します。
”views.py”のMonthly_DetailsViewに追加の記述を行いましょう。
from django.utils import timezone #追加
today = str(timezone.now()).split('-') #今日の日付 #IndexViewの上に追加
#月別詳細
class Monthly_DetailsView(View):
def get(self, request, year=int(today[0]), month=int(today[1])):
#指定月の収支データを取得
income = Income.objects.filter(date__year=year, date__month=month).order_by('-date')
expense = Expense.objects.filter(date__year=year, date__month=month).order_by('-date')
#輸入、支出の合計を取得
income_total = 0
for item in income:
income_total += item.amount
expense_total = 0
for item in expense:
expense_total += item.amount
#収支の計算
balance_payment = income_total - expense_total
#隣月の調整
if month == 12:
last_year = year
last_month = 11
next_year = year + 1
next_month = 1
elif month == 1:
last_year = year - 1
last_month = 12
next_year = year
next_month = 2
else:
last_year = year
last_month = month - 1
next_year = year
next_month = month + 1
params = {
'year': year,
'month': month,
'last_year': last_year,
'last_month': last_month,
'next_year': next_year,
'next_month': next_month,
'income': income,
'income_total': income_total,
'expense': expense,
'expense_total': expense_total,
'balance_payment': balance_payment,
}
return render(request, 'money_diary/monthly_details.html', params)
簡単に解説していきます。
3行目は本日の日付を取得し、それを”年”、”月”、”日”に分割しています。
これによって年と月を引数として渡すことができます。
Montly_DeatilsViewでは、各月の収支のデータや収入、支出の合計、月の収支をデータベースから取得しています。
24行目から38行目では、先月と翌月の年と月を取得しています。
例えば今月が2021年12月だった場合、先月は2021年11月と月を1つ戻せばよいですが、翌月は2022年1月となり、年は1つ増え月は1月に戻ります。
このような処理を場合分けして行っています。
テンプレートの作成
次に月別詳細のテンプレートを作成しましょう。
表示する項目としては、収支と月の収支項目一覧です。
“monthly_details.html”に以下のコードを記載します。
簡単にBootstrapを使用して体裁は整えていますが最低限です。
{% 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></td>
</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></td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}
4行目から20行目までは、収支のテーブルです。
22行目から36行目で表示月を表しています。
ページネーションを使用して、矢印で先月、翌月に移動ができます。
URLの設定はこの後行いますが、25行目と31行目でそれぞれ先月、翌月の値を引数として渡しています。
38行目以下は各詳細項目の一覧テーブルです。
今回は削除ボタンの実装をしていません。
次回の記事で行いたいと思います。
URLを追加する
最後にURLを追加します。
アプリケーションファイルにある”urls.py”を修正します。
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'),
]
これで終了です!
月別詳細ページの原型ができたと思います。
修正点
いじっていたら気が付いた箇所があったため、最後に今回の記事とは全く関係ない点を修正します。
収入、支出の登録を行う際に「メモ」を空白にして登録できないことに気づきました。
これは不便なため、“models.py”のメモの項目を以下のように変更しました。
#収入のモデル
class Income(models.Model):
date = models.DateField(default=timezone.now) #日付
category = models.ForeignKey(IncomeCategories, on_delete=models.CASCADE) #カテゴリ
account = models.CharField(max_length=30) #入金口座
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.ForeignKey(ExpenseCategories, on_delete=models.CASCADE) #カテゴリ
account = models.CharField(max_length=30) #出所
amount = models.IntegerField() #金額
memo = models.TextField(null=True, blank=True, max_length=100) #メモ
def __str__(self):
return self.category.name + str(self.amount)
これでメモの欄が未入力でも追加が行えると思います!
まとめ
本日は月別詳細ページの作成でした。
デザインが自分はあまりできないので見た目はよくありませんが、機能は最低限そろっているかと思います。
次回は削除ボタンの実装、保有している銀行口座の登録と収入、支出の紐づけを行いたいと思います!
最後まで読んでいただきありがとうございます。
自己学習に役立てていただけたら嬉しく思います
またSNSやブログでシェアしていただくことや、誤植などをコメントで指摘いただけたら幸いです。
次回の記事↓
コメント