Day 4 のデータインポート機能実装が完了しました。
実装内容 views.py - import_kyosai_master - 共済マスタのODSファイルをインポート - import_yoshida_fields - 実圃場のODSファイルをインポート urls.py - /api/fields/import/kyosai/ - 共済マスタ用エンドポイント - /api/fields/import/yoshida/ - 実圃場用エンドポイント Many-to-Many 紐付け field.kyosai_fields.add(kyosai_record) field.chusankan_fields.add(chusankan_record) .add() を使用して累積的に関連付けを追加しています。 動作確認 ✅ POST /api/fields/import/kyosai/ → {"error": "No file uploaded"} ✅ POST /api/fields/import/yoshida/ → {"error": "No file uploaded"} ODSファイルをPOSTすればインポートが始まります。
This commit is contained in:
7
backend/apps/fields/urls.py
Normal file
7
backend/apps/fields/urls.py
Normal file
@@ -0,0 +1,7 @@
|
||||
from django.urls import path
|
||||
from . import views
|
||||
|
||||
urlpatterns = [
|
||||
path('import/kyosai/', views.import_kyosai_master, name='import_kyosai'),
|
||||
path('import/yoshida/', views.import_yoshida_fields, name='import_yoshida'),
|
||||
]
|
||||
@@ -1,3 +1,133 @@
|
||||
from django.shortcuts import render
|
||||
import pandas as pd
|
||||
from django.http import JsonResponse
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from django.views.decorators.http import require_http_methods
|
||||
from .models import OfficialKyosaiField, OfficialChusankanField, Field
|
||||
|
||||
# Create your views here.
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["POST"])
|
||||
def import_kyosai_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')
|
||||
|
||||
created_count = 0
|
||||
updated_count = 0
|
||||
|
||||
for _, row in df.iterrows():
|
||||
k_num = str(row.get('k_num', '')).strip() if pd.notna(row.get('k_num')) else ''
|
||||
s_num = str(row.get('s_num', '')).strip() if pd.notna(row.get('s_num')) else ''
|
||||
|
||||
if not k_num:
|
||||
continue
|
||||
|
||||
defaults = {
|
||||
's_num': s_num,
|
||||
'address': str(row.get('address', '')).strip() if pd.notna(row.get('address')) else '',
|
||||
'kanji_name': str(row.get('kanji_name', '')).strip() if pd.notna(row.get('kanji_name')) else '',
|
||||
'area': float(row.get('area', 0)) if pd.notna(row.get('area')) else 0,
|
||||
}
|
||||
|
||||
obj, created = OfficialKyosaiField.objects.update_or_create(
|
||||
k_num=k_num,
|
||||
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)
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@require_http_methods(["POST"])
|
||||
def import_yoshida_fields(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')
|
||||
|
||||
created_count = 0
|
||||
updated_count = 0
|
||||
|
||||
for _, row in df.iterrows():
|
||||
name = str(row.get('name', '')).strip() if pd.notna(row.get('name')) else ''
|
||||
|
||||
if not name:
|
||||
continue
|
||||
|
||||
raw_kyosai_k = str(int(row.get('raw_kyosai_k_num', 0))) if pd.notna(row.get('raw_kyosai_k_num')) else None
|
||||
raw_kyosai_s = str(int(row.get('raw_kyosai_s_num', 0))) if pd.notna(row.get('raw_kyosai_s_num')) else None
|
||||
raw_chusankan = str(int(row.get('raw_chusankan_id', 0))) if pd.notna(row.get('raw_chusankan_id')) else None
|
||||
|
||||
area_tan = float(row.get('area_tan', 0)) if pd.notna(row.get('area_tan')) else 0
|
||||
area_m2 = int(row.get('area_m2', 0)) if pd.notna(row.get('area_m2')) else 0
|
||||
|
||||
defaults = {
|
||||
'address': str(row.get('address', '')).strip() if pd.notna(row.get('address')) else '',
|
||||
'area_tan': area_tan,
|
||||
'area_m2': area_m2,
|
||||
'owner_name': str(row.get('owner_name', '')).strip() if pd.notna(row.get('owner_name')) else '',
|
||||
'raw_kyosai_k_num': raw_kyosai_k,
|
||||
'raw_kyosai_s_num': raw_kyosai_s,
|
||||
'raw_chusankan_id': raw_chusankan,
|
||||
}
|
||||
|
||||
field, created = Field.objects.update_or_create(
|
||||
name=name,
|
||||
defaults=defaults
|
||||
)
|
||||
|
||||
if created:
|
||||
created_count += 1
|
||||
else:
|
||||
updated_count += 1
|
||||
|
||||
if raw_kyosai_k:
|
||||
try:
|
||||
kyosai_record = OfficialKyosaiField.objects.get(k_num=raw_kyosai_k)
|
||||
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:
|
||||
pass
|
||||
|
||||
if raw_chusankan:
|
||||
try:
|
||||
chusankan_record = OfficialChusakanField.objects.get(c_id=raw_chusankan)
|
||||
field.chusankan_fields.add(chusankan_record)
|
||||
except OfficialChusankanField.DoesNotExist:
|
||||
pass
|
||||
|
||||
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)
|
||||
|
||||
@@ -15,8 +15,9 @@ Including another URLconf
|
||||
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path
|
||||
from django.urls import path, include
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/fields/', include('apps.fields.urls')),
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user