実装サマリー
バックエンド(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:
@@ -3,18 +3,28 @@ from .models import Field, OfficialKyosaiField, OfficialChusankanField
|
||||
|
||||
|
||||
class OfficialKyosaiFieldSerializer(serializers.ModelSerializer):
|
||||
linked_field_names = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = OfficialKyosaiField
|
||||
fields = ['id', 'k_num', 's_num', 'address', 'kanji_name', 'area']
|
||||
fields = ['id', 'k_num', 's_num', 'address', 'kanji_name', 'area', 'linked_field_names']
|
||||
|
||||
def get_linked_field_names(self, obj):
|
||||
return list(obj.fields.values_list('name', flat=True))
|
||||
|
||||
|
||||
class OfficialChusankanFieldSerializer(serializers.ModelSerializer):
|
||||
linked_field_names = serializers.SerializerMethodField()
|
||||
|
||||
class Meta:
|
||||
model = OfficialChusankanField
|
||||
fields = ['id', 'c_id', 'chusankan_flag', 'oaza', 'aza', 'chiban', 'branch_num',
|
||||
'land_type', 'area', 'planting_area', 'original_crop', 'manager', 'owner',
|
||||
'slope', 'base_amount', 'steep_slope_addition', 'smart_agri_addition',
|
||||
'payment_amount']
|
||||
'payment_amount', 'linked_field_names']
|
||||
|
||||
def get_linked_field_names(self, obj):
|
||||
return list(obj.fields.values_list('name', flat=True))
|
||||
|
||||
|
||||
class FieldSerializer(serializers.ModelSerializer):
|
||||
|
||||
@@ -6,8 +6,12 @@ router = DefaultRouter()
|
||||
router.register(r'', views.FieldViewSet, basename='field')
|
||||
|
||||
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'),
|
||||
path('<int:field_id>/kyosai-links/', views.add_kyosai_links, name='add_kyosai_links'),
|
||||
path('<int:field_id>/kyosai-links/<int:kyosai_id>/', views.remove_kyosai_link, name='remove_kyosai_link'),
|
||||
path('<int:field_id>/chusankan-links/', views.add_chusankan_links, name='add_chusankan_links'),
|
||||
path('<int:field_id>/chusankan-links/<int:chusankan_id>/', views.remove_chusankan_link, name='remove_chusankan_link'),
|
||||
path('', include(router.urls)),
|
||||
]
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -16,11 +16,18 @@ Including another URLconf
|
||||
"""
|
||||
from django.contrib import admin
|
||||
from django.urls import path, include
|
||||
from rest_framework.routers import DefaultRouter
|
||||
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
|
||||
from apps.fields.views import OfficialKyosaiFieldViewSet, OfficialChusankanFieldViewSet
|
||||
|
||||
master_router = DefaultRouter()
|
||||
master_router.register(r'kyosai-fields', OfficialKyosaiFieldViewSet, basename='kyosai-field')
|
||||
master_router.register(r'chusankan-fields', OfficialChusankanFieldViewSet, basename='chusankan-field')
|
||||
|
||||
urlpatterns = [
|
||||
path('admin/', admin.site.urls),
|
||||
path('api/fields/', include('apps.fields.urls')),
|
||||
path('api/', include(master_router.urls)),
|
||||
path('api/plans/', include('apps.plans.urls')),
|
||||
path('api/reports/', include('apps.reports.urls')),
|
||||
path('api/auth/jwt/create/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||
|
||||
Reference in New Issue
Block a user