Files
Ai/plant/views.py
T

307 lines
11 KiB
Python
Raw Normal View History

2026-03-19 22:54:29 +03:30
from drf_spectacular.utils import (
OpenApiExample,
OpenApiResponse,
extend_schema,
inline_serializer,
)
from rest_framework import serializers as drf_serializers
from rest_framework import status
from rest_framework.response import Response
from rest_framework.views import APIView
2026-03-25 01:56:41 +03:30
from config.openapi import build_envelope_serializer, build_response
2026-03-19 22:54:29 +03:30
from .models import Plant
from .serializers import PlantSerializer
from .services import fetch_plant_info_from_api
2026-03-25 01:56:41 +03:30
PlantListResponseSerializer = build_envelope_serializer(
"PlantListResponseSerializer",
PlantSerializer,
many=True,
)
PlantDetailResponseSerializer = build_envelope_serializer(
"PlantDetailResponseSerializer",
PlantSerializer,
)
PlantValidationErrorSerializer = build_envelope_serializer(
"PlantValidationErrorSerializer",
data_required=False,
allow_null=True,
)
PlantFetchInfoResponseSerializer = build_envelope_serializer(
"PlantFetchInfoResponseSerializer",
PlantSerializer,
)
2026-03-19 22:54:29 +03:30
class PlantListCreateView(APIView):
"""لیست تمام گیاهان و ایجاد گیاه جدید."""
@extend_schema(
tags=["Plant"],
summary="لیست گیاهان",
description="لیست تمام گیاهان ذخیره‌شده را برمی‌گرداند.",
2026-03-25 01:56:41 +03:30
responses={
200: build_response(
PlantListResponseSerializer,
"لیست گیاهان ذخیره‌شده.",
),
},
2026-03-19 22:54:29 +03:30
)
def get(self, request):
plants = Plant.objects.all()
serializer = PlantSerializer(plants, many=True)
return Response(
{"code": 200, "msg": "success", "data": serializer.data},
status=status.HTTP_200_OK,
)
@extend_schema(
tags=["Plant"],
summary="ایجاد گیاه جدید",
description="یک گیاه جدید با مشخصات داده‌شده ایجاد می‌کند.",
request=PlantSerializer,
responses={
2026-03-25 01:56:41 +03:30
201: build_response(
PlantDetailResponseSerializer,
"گیاه جدید با موفقیت ایجاد شد.",
),
400: build_response(
PlantValidationErrorSerializer,
"داده ورودی نامعتبر است.",
),
2026-03-19 22:54:29 +03:30
},
examples=[
OpenApiExample(
"نمونه درخواست",
value={
"name": "گوجه‌فرنگی",
"light": "آفتاب کامل",
"watering": "منظم، هفته‌ای ۲-۳ بار",
"soil": "لومی، غنی از مواد آلی",
"temperature": "۲۰-۳۰ درجه سانتی‌گراد",
2026-04-24 02:50:27 +03:30
"growth_stage": "رشد رویشی",
2026-03-19 22:54:29 +03:30
"planting_season": "بهار",
"harvest_time": "۷۰-۹۰ روز پس از کاشت",
"spacing": "۴۵-۶۰ سانتی‌متر",
"fertilizer": "کود NPK متعادل",
},
request_only=True,
),
],
)
def post(self, request):
serializer = PlantSerializer(data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
serializer.save()
return Response(
{"code": 201, "msg": "success", "data": serializer.data},
status=status.HTTP_201_CREATED,
)
class PlantDetailView(APIView):
"""دریافت، ویرایش و حذف یک گیاه."""
def _get_plant(self, pk):
return Plant.objects.filter(pk=pk).first()
@extend_schema(
tags=["Plant"],
summary="جزئیات گیاه",
description="مشخصات یک گیاه را بر اساس شناسه برمی‌گرداند.",
responses={
2026-03-25 01:56:41 +03:30
200: build_response(
PlantDetailResponseSerializer,
"جزئیات گیاه.",
),
404: build_response(
PlantValidationErrorSerializer,
"گیاه یافت نشد.",
),
2026-03-19 22:54:29 +03:30
},
)
def get(self, request, pk):
plant = self._get_plant(pk)
if not plant:
return Response(
{"code": 404, "msg": "گیاه یافت نشد.", "data": None},
status=status.HTTP_404_NOT_FOUND,
)
serializer = PlantSerializer(plant)
return Response(
{"code": 200, "msg": "success", "data": serializer.data},
status=status.HTTP_200_OK,
)
@extend_schema(
tags=["Plant"],
summary="ویرایش کامل گیاه",
description="تمام فیلدهای یک گیاه را آپدیت می‌کند.",
request=PlantSerializer,
responses={
2026-03-25 01:56:41 +03:30
200: build_response(
PlantDetailResponseSerializer,
"گیاه با موفقیت به‌روزرسانی شد.",
),
400: build_response(
PlantValidationErrorSerializer,
"داده ورودی نامعتبر است.",
),
404: build_response(
PlantValidationErrorSerializer,
"گیاه یافت نشد.",
),
2026-03-19 22:54:29 +03:30
},
)
def put(self, request, pk):
plant = self._get_plant(pk)
if not plant:
return Response(
{"code": 404, "msg": "گیاه یافت نشد.", "data": None},
status=status.HTTP_404_NOT_FOUND,
)
serializer = PlantSerializer(plant, data=request.data)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
serializer.save()
return Response(
{"code": 200, "msg": "success", "data": serializer.data},
status=status.HTTP_200_OK,
)
@extend_schema(
tags=["Plant"],
summary="ویرایش جزئی گیاه",
description="فقط فیلدهای ارسال‌شده آپدیت می‌شوند.",
request=PlantSerializer,
responses={
2026-03-25 01:56:41 +03:30
200: build_response(
PlantDetailResponseSerializer,
"گیاه با موفقیت به‌روزرسانی شد.",
),
400: build_response(
PlantValidationErrorSerializer,
"داده ورودی نامعتبر است.",
),
404: build_response(
PlantValidationErrorSerializer,
"گیاه یافت نشد.",
),
2026-03-19 22:54:29 +03:30
},
)
def patch(self, request, pk):
plant = self._get_plant(pk)
if not plant:
return Response(
{"code": 404, "msg": "گیاه یافت نشد.", "data": None},
status=status.HTTP_404_NOT_FOUND,
)
serializer = PlantSerializer(plant, data=request.data, partial=True)
if not serializer.is_valid():
return Response(
{"code": 400, "msg": "داده نامعتبر.", "data": serializer.errors},
status=status.HTTP_400_BAD_REQUEST,
)
serializer.save()
return Response(
{"code": 200, "msg": "success", "data": serializer.data},
status=status.HTTP_200_OK,
)
@extend_schema(
tags=["Plant"],
summary="حذف گیاه",
description="یک گیاه را حذف می‌کند.",
responses={
2026-03-25 01:56:41 +03:30
200: build_response(
PlantValidationErrorSerializer,
"گیاه با موفقیت حذف شد.",
),
404: build_response(
PlantValidationErrorSerializer,
"گیاه یافت نشد.",
),
2026-03-19 22:54:29 +03:30
},
)
def delete(self, request, pk):
plant = self._get_plant(pk)
if not plant:
return Response(
{"code": 404, "msg": "گیاه یافت نشد.", "data": None},
status=status.HTTP_404_NOT_FOUND,
)
plant.delete()
return Response(
{"code": 200, "msg": "گیاه با موفقیت حذف شد.", "data": None},
status=status.HTTP_200_OK,
)
class PlantFetchInfoView(APIView):
"""دریافت مشخصات گیاه از API خارجی بر اساس نام."""
@extend_schema(
tags=["Plant"],
summary="دریافت مشخصات گیاه از API خارجی",
description="بر اساس نام گیاه، مشخصات آن را از API خارجی دریافت می‌کند. (فعلاً خالی)",
request=inline_serializer(
name="PlantFetchInfoRequest",
fields={
"name": drf_serializers.CharField(help_text="نام گیاه"),
},
),
responses={
2026-03-25 01:56:41 +03:30
200: build_response(
PlantFetchInfoResponseSerializer,
"اطلاعات گیاه از سرویس خارجی دریافت شد.",
),
400: build_response(
PlantValidationErrorSerializer,
"نام گیاه ارسال نشده است.",
),
503: build_response(
PlantValidationErrorSerializer,
"سرویس خارجی در دسترس نیست.",
),
2026-03-19 22:54:29 +03:30
},
examples=[
OpenApiExample(
"نمونه درخواست",
value={"name": "گوجه‌فرنگی"},
request_only=True,
),
],
)
def post(self, request):
plant_name = request.data.get("name")
if not plant_name:
return Response(
{"code": 400, "msg": "نام گیاه الزامی است.", "data": None},
status=status.HTTP_400_BAD_REQUEST,
)
result = fetch_plant_info_from_api(plant_name)
if result is None:
return Response(
{
"code": 503,
"msg": "سرویس API هنوز پیاده‌سازی نشده است.",
"data": None,
},
status=status.HTTP_503_SERVICE_UNAVAILABLE,
)
return Response(
{"code": 200, "msg": "success", "data": result},
status=status.HTTP_200_OK,
)