From 987b7572b7886de390e36c42c4b80a5b2251e165 Mon Sep 17 00:00:00 2001 From: Akira Date: Sun, 15 Feb 2026 14:19:15 +0900 Subject: [PATCH] =?UTF-8?q?=E4=B8=8B=E8=A8=98=E3=81=AE=E9=80=9A=E3=82=8A?= =?UTF-8?q?=E3=81=8A=E8=BF=94=E4=BA=8B=E3=81=8D=E3=81=BE=E3=81=97=E3=81=9F?= =?UTF-8?q?=E3=81=AE=E3=81=A7=E3=80=81=E5=AE=9F=E3=83=87=E3=83=BC=E3=82=BF?= =?UTF-8?q?=E3=81=A7=E3=83=86=E3=82=B9=E3=83=88=E3=81=97=E3=81=A6=E3=81=8F?= =?UTF-8?q?=E3=81=A0=E3=81=95=E3=81=84=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/apps/fields/urls.py | 1 + backend/apps/fields/views.py | 61 +++++++++++++++++++++++++++++++----- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/backend/apps/fields/urls.py b/backend/apps/fields/urls.py index a071d2d..7f31e37 100644 --- a/backend/apps/fields/urls.py +++ b/backend/apps/fields/urls.py @@ -9,4 +9,5 @@ urlpatterns = [ path('', include(router.urls)), path('import/kyosai/', views.import_kyosai_master, name='import_kyosai'), path('import/yoshida/', views.import_yoshida_fields, name='import_yoshida'), + path('import/chusankan/', views.import_chusankan_master, name='import_chusankan'), ] diff --git a/backend/apps/fields/views.py b/backend/apps/fields/views.py index e7bd8cb..58824cb 100644 --- a/backend/apps/fields/views.py +++ b/backend/apps/fields/views.py @@ -112,18 +112,13 @@ def import_yoshida_fields(request): else: updated_count += 1 - if raw_kyosai_k: + if raw_kyosai_k and raw_kyosai_s: try: - kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k) + kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k, s_num=raw_kyosai_s) field.kyosai_fields.add(kyosai_record) except OfficialKyosaiField.DoesNotExist: pass - - if raw_kyosai_s: - try: - kyosai_record = OfficialKyosaiField.objects.get(s_num=raw_kyosai_s) - field.kyosai_fields.add(kyosai_record) - except OfficialKyosaiField.DoesNotExist: + except OfficialKyosaiField.MultipleObjectsReturned: pass if raw_chusankan: @@ -142,3 +137,53 @@ def import_yoshida_fields(request): except Exception as e: return JsonResponse({'error': str(e)}, status=500) + + +@csrf_exempt +@require_http_methods(["POST"]) +def import_chusankan_master(request): + if 'file' not in request.FILES: + return JsonResponse({'error': 'No file uploaded'}, status=400) + + ods_file = request.FILES['file'] + + try: + df = pd.read_excel(ods_file, engine='odf') + df.columns = df.columns.str.strip() + + created_count = 0 + updated_count = 0 + + for _, row in df.iterrows(): + c_id = str(row.get('ID', '')).strip() if pd.notna(row.get('ID')) else '' + + if not c_id: + continue + + defaults = { + 'oaza': str(row.get('大字', '')).strip() if pd.notna(row.get('大字')) else '', + 'aza': str(row.get('字', '')).strip() if pd.notna(row.get('字')) else '', + 'chiban': str(row.get('地番', '')).strip() if pd.notna(row.get('地番')) else '', + 'area': float(row.get('農地面積', 0)) if pd.notna(row.get('農地面積')) else 0, + 'payment_amount': int(row.get('交付金額', 0)) if pd.notna(row.get('交付金額')) else None, + } + + obj, created = OfficialChusankanField.objects.update_or_create( + c_id=c_id, + defaults=defaults + ) + + if created: + created_count += 1 + else: + updated_count += 1 + + return JsonResponse({ + 'success': True, + 'created': created_count, + 'updated': updated_count, + 'message': f'中山間マスタ: {created_count}件作成, {updated_count}件更新' + }) + + except Exception as e: + return JsonResponse({'error': str(e)}, status=500)