Sensor Data Collector後端資料模型實作建議 by ChatGPT --- Q: 我要規劃一個IoT感測器資料搜集平台,本系統的參與角色有以下: 1. 雲端系統:後端API使用Django搭配Rest-framework實作,包含資料輸入與匯出功能。前端使用Vue.js實作,包含管理介面、資料展示Dashboard、帳號權限設定等。資料庫使用PostgreSQL16.3,系統架構使用docker進行架設。每個平台使用者皆隸屬於某客戶公司,使用者可加入不同角色(Groups)。 2. Device:地端蒐集器,負責集中處理所有地端Sensor Data,並上傳給雲端系統。每個設備皆會隸屬於某間公司,一個設備可以連接管理多個感測器。 3. Sensor:感測器,有多種感測器包含但不限於溫度、濕度、PM2.5、PM10、照度等。Sensor種類可以直接在後台進行管理,包含該Sensor回傳的資料型態、最大最小值等。 請先幫我撰寫適合後端用的models。 帳號權限我想用Django原生的User(使用onetoone擴充)與Group實作。 程式架構請用以下應用分類: accounts devices sensors --- A: 根據您的需求,我將根據 Django 的最佳實踐,將模型分別放在 `accounts`、`devices` 和 `sensors` 三個應用中。以下是每個應用的 `models.py` 文件內容,包括相關的模型定義和關聯設定。 ### 1. `accounts` 應用 此應用主要負責用戶帳號管理,包括公司資訊和用戶擴充資料。 ```python # accounts/models.py from django.db import models from django.contrib.auth.models import User from django.db.models.signals import post_save from django.dispatch import receiver class Company(models.Model): """ 公司模型,每個用戶隸屬於某個公司。 """ name = models.CharField(max_length=255, unique=True) address = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.name class Profile(models.Model): """ 用戶擴充模型,透過 OneToOneField 擴充 Django 原生 User 模型。 """ user = models.OneToOneField(User, on_delete=models.CASCADE, related_name='profile') company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='users') # 其他擴充欄位可以在此添加,例如電話、地址等 phone = models.CharField(max_length=20, blank=True, null=True) def __str__(self): return f"{self.user.username} Profile" # Signal 來自動建立或更新 Profile @receiver(post_save, sender=User) def create_or_update_user_profile(sender, instance, created, **kwargs): if created: Profile.objects.create(user=instance) instance.profile.save() ``` **說明:** - **Company 模型**:儲存公司相關資訊,每個用戶和設備都會關聯到一個公司。 - **Profile 模型**:擴充 Django 的 `User` 模型,透過 `OneToOneField` 與 `User` 相關聯,並新增 `company` 欄位來表示用戶所屬的公司。您可以根據需要在此模型中添加更多擴充欄位。 - **Signal**:當 `User` 創建或更新時,自動創建或更新對應的 `Profile`。 ### 2. `devices` 應用 此應用負責管理設備(Device),每個設備隸屬於一個公司,並可管理多個感測器。 ```python # devices/models.py from django.db import models from accounts.models import Company from django.contrib.auth.models import User class Device(models.Model): """ 設備模型,每個設備隸屬於某個公司,並可以管理多個感測器。 """ name = models.CharField(max_length=255) device_id = models.CharField(max_length=100, unique=True) company = models.ForeignKey(Company, on_delete=models.CASCADE, related_name='devices') description = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.name} ({self.device_id})" ``` **說明:** - **Device 模型**:包含設備名稱、唯一的 `device_id`、所屬公司以及其他描述性欄位。 - **關聯**:每個設備透過 `ForeignKey` 關聯到 `Company`,確保設備屬於特定公司。 ### 3. `sensors` 應用 此應用負責管理感測器類型和具體的感測器實例。 ```python # sensors/models.py from django.db import models from devices.models import Device class SensorType(models.Model): """ 感測器類型模型,用於管理不同種類的感測器。 """ DATA_TYPE_CHOICES = [ ('float', 'Float'), ('integer', 'Integer'), ('string', 'String'), ('boolean', 'Boolean'), # 根據需要添加更多資料型態 ] name = models.CharField(max_length=100, unique=True) data_type = models.CharField(max_length=50, choices=DATA_TYPE_CHOICES) min_value = models.FloatField(blank=True, null=True) max_value = models.FloatField(blank=True, null=True) description = models.TextField(blank=True, null=True) def __str__(self): return self.name class Sensor(models.Model): """ 感測器模型,每個感測器隸屬於某個設備,並有特定的感測器類型。 """ name = models.CharField(max_length=255) sensor_id = models.CharField(max_length=100, unique=True) device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='sensors') sensor_type = models.ForeignKey(SensorType, on_delete=models.PROTECT, related_name='sensors') description = models.TextField(blank=True, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return f"{self.name} ({self.sensor_id})" class Meta: unique_together = ('device', 'sensor_id') ``` **說明:** - **SensorType 模型**:管理不同類型的感測器,包括名稱、資料型態、最小值和最大值等。`DATA_TYPE_CHOICES` 定義了感測器資料的可能型態。 - **Sensor 模型**:代表具體的感測器實例,包含感測器名稱、唯一的 `sensor_id`、所屬設備以及感測器類型。`unique_together` 確保同一設備下的 `sensor_id` 唯一。 - **關聯**: - 每個感測器透過 `ForeignKey` 關聯到 `Device`,確保感測器屬於特定設備。 - 每個感測器透過 `ForeignKey` 關聯到 `SensorType`,確保感測器具有特定的類型定義。 ### 4. 其他建議 **使用 Docker 部署:** 確保在 `Dockerfile` 和 `docker-compose.yml` 中正確配置這些應用的相依性和服務。例如,確保 PostgreSQL 服務正確設定,並且每個應用的資料庫遷移能夠順利進行。 **權限管理:** 利用 Django 的 `Group` 模型來管理不同角色的權限。在 `accounts` 應用中,您可以根據需求創建不同的群組(例如:管理員、一般使用者等),並分配適當的權限。 **資料驗證與約束:** 根據需求,您可以在模型中添加更多的驗證邏輯,例如在 `Sensor` 模型中確保 `sensor_id` 的格式,或在 `SensorType` 模型中根據 `data_type` 限制 `min_value` 和 `max_value` 的適用性。 **範例管理命令:** 在每個應用中創建相應的 `admin.py` 文件,讓您能夠透過 Django 管理介面管理這些模型。 ```python # accounts/admin.py from django.contrib import admin from .models import Company, Profile admin.site.register(Company) admin.site.register(Profile) ``` ```python # devices/admin.py from django.contrib import admin from .models import Device admin.site.register(Device) ``` ```python # sensors/admin.py from django.contrib import admin from .models import SensorType, Sensor admin.site.register(SensorType) admin.site.register(Sensor) ```