実装サマリー

バックエンド(3ファイル変更)
ファイル	変更内容
views.py	OfficialKyosaiFieldViewSet、OfficialChusankanFieldViewSet(ReadOnly)、紐づけ追加/解除の4つのAPIビューを追加
urls.py	紐づけ管理用の4パス追加
serializers.py	linked_field_namesフィールドを追加(紐づけ先の圃場名を返す)
keinasystem/urls.py	/api/kyosai-fields/、/api/chusankan-fields/ をルーターに登録
新規API一覧
メソッド	エンドポイント	動作確認
GET	/api/kyosai-fields/	31件返却
GET	/api/chusankan-fields/	71件返却
POST	/api/fields/{id}/kyosai-links/	{"added":1}
DELETE	/api/fields/{id}/kyosai-links/{kyosai_id}/	204
POST	/api/fields/{id}/chusankan-links/	同上
DELETE	/api/fields/{id}/chusankan-links/{chusankan_id}/	同上
フロントエンド(3ファイル変更)
ファイル	変更内容
types/index.ts	linked_field_namesプロパティ追加
fields/[id]/page.tsx	紐づけ管理UI全面実装(+追加ボタン、x解除ボタン、検索付きモーダル、面積参考表示)
fields/page.tsx	「共済」「中山間」紐づけ件数列を追加
http://localhost:3000/fields/4 などで圃場詳細画面を開いて動作確認できます。
This commit is contained in:
Akira
2026-02-18 14:02:40 +09:00
parent 619bd7886e
commit 64e7701456
8 changed files with 443 additions and 79 deletions

View File

@@ -1,12 +1,14 @@
import pandas as pd
from django.db import models as django_models
from django.http import JsonResponse
from django.shortcuts import get_object_or_404
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods
from rest_framework import viewsets, permissions, filters
from rest_framework.decorators import action
from rest_framework import viewsets, permissions, filters, status
from rest_framework.decorators import action, api_view, permission_classes as perm_classes
from rest_framework.response import Response
from .models import OfficialKyosaiField, OfficialChusankanField, Field
from .serializers import FieldSerializer
from .serializers import FieldSerializer, OfficialKyosaiFieldSerializer, OfficialChusankanFieldSerializer
class FieldViewSet(viewsets.ModelViewSet):
@@ -21,6 +23,56 @@ class FieldViewSet(viewsets.ModelViewSet):
ordering_fields = ['group_name', 'display_order', 'id', 'area_tan']
class OfficialKyosaiFieldViewSet(viewsets.ReadOnlyModelViewSet):
queryset = OfficialKyosaiField.objects.all().order_by('k_num', 's_num')
serializer_class = OfficialKyosaiFieldSerializer
permission_classes = [permissions.IsAuthenticated]
class OfficialChusankanFieldViewSet(viewsets.ReadOnlyModelViewSet):
queryset = OfficialChusankanField.objects.all().order_by('c_id')
serializer_class = OfficialChusankanFieldSerializer
permission_classes = [permissions.IsAuthenticated]
@api_view(['POST'])
@perm_classes([permissions.IsAuthenticated])
def add_kyosai_links(request, field_id):
field = get_object_or_404(Field, pk=field_id)
ids = request.data.get('kyosai_field_ids', [])
records = OfficialKyosaiField.objects.filter(id__in=ids)
field.kyosai_fields.add(*records)
return Response({'added': len(records)})
@api_view(['DELETE'])
@perm_classes([permissions.IsAuthenticated])
def remove_kyosai_link(request, field_id, kyosai_id):
field = get_object_or_404(Field, pk=field_id)
kyosai = get_object_or_404(OfficialKyosaiField, pk=kyosai_id)
field.kyosai_fields.remove(kyosai)
return Response(status=status.HTTP_204_NO_CONTENT)
@api_view(['POST'])
@perm_classes([permissions.IsAuthenticated])
def add_chusankan_links(request, field_id):
field = get_object_or_404(Field, pk=field_id)
ids = request.data.get('chusankan_field_ids', [])
records = OfficialChusankanField.objects.filter(id__in=ids)
field.chusankan_fields.add(*records)
return Response({'added': len(records)})
@api_view(['DELETE'])
@perm_classes([permissions.IsAuthenticated])
def remove_chusankan_link(request, field_id, chusankan_id):
field = get_object_or_404(Field, pk=field_id)
chusankan = get_object_or_404(OfficialChusankanField, pk=chusankan_id)
field.chusankan_fields.remove(chusankan)
return Response(status=status.HTTP_204_NO_CONTENT)
@csrf_exempt
@require_http_methods(["POST"])
def import_kyosai_master(request):