ドキュメント更新(6ファイル)

03_データ仕様書.md — 全面書き直し(M:N関係、中山間17列モデル、面積単位、PDF出力仕様)
04_画面設計書.md — 全面書き直し(Navbar追加、圃場管理/新規作成画面追加、インライン編集方式、PDF帳票フォーマット仕様 E-1)
01_プロダクトビジョン.md — CSV→PDF、M:1→M:N
05_実装優先順位.md — CSV→PDF、Django 5.0→5.2、モーダル→インライン、init_crops削除
00_Gemini向け統合指示書.md — CSV→PDF、Django 5.2、M:N関係、中山間17列モデル、init_crops削除、IsAuthenticated
CLAUDE.md — 既知の課題一覧、次タスク優先順追加、中山間モデル拡張、差異レポートリンク
コード修正(4件)
D-1: reports/views.py — plan.crop / plan.variety の null チェック追加
D-2: init_crops.py を削除
D-3: settings.py — LANGUAGE_CODE/TIME_ZONE の二重定義を解消
D-4: settings.py — AllowAny → IsAuthenticated に変更
次のタスクは CLAUDE.md の優先順リストに従うと A-8(圃場詳細に共済/中山間情報表示)です。続けますか?
This commit is contained in:
Akira
2026-02-17 10:56:09 +09:00
parent 9c21caa017
commit 50e23872f3
11 changed files with 771 additions and 738 deletions

View File

@@ -1,38 +0,0 @@
from django.core.management.base import BaseCommand
from apps.plans.models import Crop, Variety
class Command(BaseCommand):
help = 'Initialize crops and varieties master data'
def handle(self, *args, **options):
crops_data = [
{
'name': '水稲',
'varieties': ['コシヒカリ', 'ひとめぼれ', 'あきたこまち', 'つや姫', 'oniai']
},
{
'name': '大豆',
'varieties': ['タマホマレ', 'エンレイ', 'ミヤギром']
},
{
'name': '小麦',
'varieties': ['キタノカオリ', 'ホウライ']
},
{
'name': 'そば',
'varieties': ['信濃一号', 'はるか']
},
{
'name': 'とうきび',
'varieties': ['ゴールdent']
},
]
for crop_data in crops_data:
crop, _ = Crop.objects.get_or_create(name=crop_data['name'])
for variety_name in crop_data['varieties']:
Variety.objects.get_or_create(crop=crop, name=variety_name)
self.stdout.write(f'{crop.name}: {len(crop_data["varieties"])} varieties')
self.stdout.write(self.style.SUCCESS('Successfully initialized crops and varieties'))

View File

@@ -1,4 +1,3 @@
from django.shortcuts import render
from django.template.loader import render_to_string
from django.http import HttpResponse
from weasyprint import HTML
@@ -8,25 +7,25 @@ from apps.plans.models import Plan
def generate_kyosai_pdf(request, year):
kyosai_fields = OfficialKyosaiField.objects.all()
data = []
for kyosai in kyosai_fields:
related_fields = kyosai.fields.all()
plans = Plan.objects.filter(field__in=related_fields, year=year)
crops = {}
total_area = 0
for plan in plans:
crop_name = plan.crop.name
crop_name = plan.crop.name if plan.crop else '未設定'
if crop_name not in crops:
crops[crop_name] = {
'name': crop_name,
'variety': plan.variety.name,
'variety': plan.variety.name if plan.variety else '',
'count': 0
}
crops[crop_name]['count'] += 1
total_area += float(plan.field.area_tan)
data.append({
'kyosai': kyosai,
'fields': related_fields,
@@ -34,14 +33,14 @@ def generate_kyosai_pdf(request, year):
'total_area': total_area,
'field_count': related_fields.count()
})
html_string = render_to_string('reports/kyosai_template.html', {
'year': year,
'data': data
})
pdf = HTML(string=html_string).write_pdf()
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="kyosai_{year}.pdf"'
return response
@@ -49,25 +48,25 @@ def generate_kyosai_pdf(request, year):
def generate_chusankan_pdf(request, year):
chusankan_fields = OfficialChusankanField.objects.all()
data = []
for chusankan in chusankan_fields:
related_fields = chusankan.fields.all()
plans = Plan.objects.filter(field__in=related_fields, year=year)
crops = {}
total_area = 0
for plan in plans:
crop_name = plan.crop.name
crop_name = plan.crop.name if plan.crop else '未設定'
if crop_name not in crops:
crops[crop_name] = {
'name': crop_name,
'variety': plan.variety.name,
'variety': plan.variety.name if plan.variety else '',
'count': 0
}
crops[crop_name]['count'] += 1
total_area += float(plan.field.area_tan)
data.append({
'chusankan': chusankan,
'fields': related_fields,
@@ -75,14 +74,14 @@ def generate_chusankan_pdf(request, year):
'total_area': total_area,
'field_count': related_fields.count()
})
html_string = render_to_string('reports/chusankan_template.html', {
'year': year,
'data': data
})
pdf = HTML(string=html_string).write_pdf()
response = HttpResponse(pdf, content_type='application/pdf')
response['Content-Disposition'] = f'attachment; filename="chusankan_{year}.pdf"'
return response

View File

@@ -110,9 +110,9 @@ AUTH_PASSWORD_VALIDATORS = [
# Internationalization
# https://docs.djangoproject.com/en/5.2/topics/i18n/
LANGUAGE_CODE = 'en-us'
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'UTC'
TIME_ZONE = 'Asia/Tokyo'
USE_I18N = True
@@ -134,7 +134,7 @@ REST_FRAMEWORK = {
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
'DEFAULT_PERMISSION_CLASSES': (
'rest_framework.permissions.AllowAny',
'rest_framework.permissions.IsAuthenticated',
),
}
@@ -148,7 +148,3 @@ CORS_ALLOWED_ORIGINS = [
"http://localhost:3000",
"http://127.0.0.1:3000",
]
LANGUAGE_CODE = 'ja'
TIME_ZONE = 'Asia/Tokyo'