8.9 KiB
مستند API کاتالوگ سنسورها
این فایل API ثبتشده در sensor_catalog/urls.py را بهصورت کامل توضیح میدهد.
فایل route
فایل route این app:
sensor_catalog/urls.py
محتوای آن:
from django.urls import path
from .views import SensorCatalogListView
urlpatterns = [
path("", SensorCatalogListView.as_view(), name="sensor-catalog-list"),
]
آدرس نهایی endpoint
این route در config/urls.py اینطور mount شده است:
path("api/sensor-catalog/", include("sensor_catalog.urls"))
پس آدرس نهایی API این است:
GET /api/sensor-catalog/
هدف API
این endpoint برای گرفتن لیست کاتالوگ سنسورها استفاده میشود.
منظور از کاتالوگ سنسور، تعریف مرجع هر نوع سنسور است؛ مثلا:
- کد سنسور
- نام سنسور
- توضیحات
- فیلدهای خروجی سنسور
- نمونه payload
- منبع تغذیههای پشتیبانیشده
این API بیشتر برای frontend یا تنظیمات سیستم مفید است تا بداند چه نوع سنسورهایی در سیستم تعریف شدهاند و هر سنسور چه ساختاری دارد.
View مربوطه
این endpoint در فایل sensor_catalog/views.py پیادهسازی شده است:
class SensorCatalogListView(APIView):
permission_classes = [IsAuthenticated]
این یعنی:
- فقط متد
GETپشتیبانی میشود - کاربر باید authenticated باشد
احراز هویت و دسترسی
این View از:
permission_classes = [IsAuthenticated]
استفاده میکند.
در این پروژه بهصورت پیشفرض authentication از طریق JWT انجام میشود، چون در config/settings.py مقدار زیر تعریف شده:
"DEFAULT_AUTHENTICATION_CLASSES": [
"rest_framework_simplejwt.authentication.JWTAuthentication",
]
پس اگر کاربر توکن معتبر نداشته باشد، این API پاسخ 401 Unauthorized برمیگرداند.
رفتار endpoint
در متد get این View:
def get(self, request):
sensors = SensorCatalog.objects.order_by("code")
data = SensorCatalogSerializer(sensors, many=True).data
return Response({"code": 200, "msg": "success", "data": data}, status=status.HTTP_200_OK)
این منطق اجرا میشود:
- همه رکوردهای
SensorCatalogاز دیتابیس خوانده میشوند - خروجی بر اساس
codeمرتب میشود - دادهها با serializer به JSON تبدیل میشوند
- پاسخ استاندارد با
codeوmsgوdataبرگردانده میشود
مدل دیتابیس
مدل این API در sensor_catalog/models.py قرار دارد:
class SensorCatalog(models.Model):
uuid = models.UUIDField(default=uuid.uuid4, unique=True, editable=False, db_index=True)
code = models.CharField(max_length=255, unique=True, db_index=True)
name = models.CharField(max_length=255, unique=True, db_index=True)
description = models.TextField(blank=True, default="")
customizable_fields = models.JSONField(default=list, blank=True)
supported_power_sources = models.JSONField(default=list, blank=True)
returned_data_fields = models.JSONField(default=list, blank=True)
sample_payload = models.JSONField(default=dict, blank=True)
is_active = models.BooleanField(default=True)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
معنی فیلدها
uuid: شناسه یکتا برای هر کاتالوگcode: کد یکتا و فنی سنسورname: نام قابل نمایش سنسورdescription: توضیح سنسورcustomizable_fields: فیلدهایی که موقع ساخت/پیکربندی سنسور ممکن است قابل تنظیم باشندsupported_power_sources: نوع منبع تغذیههای پشتیبانیشدهreturned_data_fields: فیلدهایی که این سنسور در payload خود برمیگرداندsample_payload: یک نمونه payload برای درک ساختار دادهis_active: فعال یا غیرفعال بودن این کاتالوگcreated_atوupdated_at: زمان ایجاد و آخرین بروزرسانی
Serializer خروجی
serializer این endpoint در sensor_catalog/serializers.py تعریف شده است:
class SensorCatalogSerializer(serializers.ModelSerializer):
class Meta:
model = SensorCatalog
fields = [
"uuid",
"code",
"name",
"description",
"customizable_fields",
"supported_power_sources",
"returned_data_fields",
"sample_payload",
"is_active",
]
read_only_fields = fields
نکته مهم
این serializer فقط این فیلدها را در خروجی برمیگرداند:
uuidcodenamedescriptioncustomizable_fieldssupported_power_sourcesreturned_data_fieldssample_payloadis_active
پس فیلدهای created_at و updated_at در پاسخ این API نیستند.
ورودی API
این endpoint ورودی body یا query param خاصی ندارد.
فقط کافی است کاربر authenticated باشد.
نمونه درخواست
GET /api/sensor-catalog/
Authorization: Bearer <access_token>
خروجی موفق
نمونه پاسخ موفق:
{
"code": 200,
"msg": "success",
"data": [
{
"uuid": "11111111-1111-1111-1111-111111111111",
"code": "sensor_7_soil_moisture_sensor_v1_2",
"name": "Sensor 7 - Soil Moisture Sensor v1.2",
"description": "Measures only soil moisture using electrical resistance between two metal probes.",
"customizable_fields": [],
"supported_power_sources": ["solar", "direct_power"],
"returned_data_fields": ["soil_moisture", "analog_output", "digital_output"],
"sample_payload": {
"soil_moisture": 42,
"analog_output": 610,
"digital_output": 1
},
"is_active": true
},
{
"uuid": "22222222-2222-2222-2222-222222222222",
"code": "legacy_sensor",
"name": "Legacy Sensor",
"description": "",
"customizable_fields": [],
"supported_power_sources": ["direct_power"],
"returned_data_fields": ["status"],
"sample_payload": {
"status": "offline"
},
"is_active": false
}
]
}
ترتیب خروجی
خروجی با این دستور مرتب میشود:
SensorCatalog.objects.order_by("code")
یعنی لیست همیشه بر اساس code به صورت صعودی برگردانده میشود.
سناریوهای کاربردی
این API معمولا برای این موارد استفاده میشود:
- ساخت dropdown برای انتخاب نوع سنسور
- نمایش ساختار داده قابل انتظار از یک سنسور
- فهمیدن اینکه هر سنسور چه فیلدهایی برمیگرداند
- ساخت فرمهای داینامیک برای پیکربندی سنسور
- نمایش
sample_payloadدر Swagger یا UI مدیریتی
وضعیتهای خطا
401 Unauthorized
اگر کاربر login نباشد یا توکن معتبر نداشته باشد.
200 با لیست خالی
اگر هیچ رکوردی در جدول sensor_catalogs وجود نداشته باشد، پاسخ موفق است اما data خالی خواهد بود:
{
"code": 200,
"msg": "success",
"data": []
}
تست موجود
برای این endpoint تست در فایل sensor_catalog/tests.py وجود دارد.
تست اصلی بررسی میکند که:
- کاربر authenticated بتواند endpoint را صدا بزند
- پاسخ
200باشد - همه سنسورهای موجود برگردانده شوند
نمونه assertion:
self.assertEqual(response.status_code, 200)
self.assertEqual(response.data["code"], 200)
self.assertEqual(len(response.data["data"]), 2)
خلاصه
API موجود در sensor_catalog/urls.py فقط یک endpoint دارد:
GET /api/sensor-catalog/
این endpoint:
- نیاز به احراز هویت دارد
- همه کاتالوگهای سنسور را از دیتابیس میخواند
- آنها را بر اساس
codeمرتب میکند - اطلاعات ساختاری سنسورها را برای frontend یا پنل مدیریتی برمیگرداند
فایلهای مرتبط
sensor_catalog/urls.pysensor_catalog/views.pysensor_catalog/serializers.pysensor_catalog/models.pysensor_catalog/tests.pyconfig/urls.py