You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django DRF类视图架构下特定系统相机与视觉模块关联数据的API设计咨询

DRF API设计:System关联Camera与Vision数据结构的实现建议

根据你的业务场景和DRF的最佳实践,我来逐一解答你的疑问:

1. 视图应该放在哪个应用?

建议将这个视图放在Systems应用中,理由如下:

  • 你的需求核心是针对某个已知的System获取关联的Camera和Vision数据,属于System资源的聚合查询逻辑,放在Systems应用能保持资源逻辑的内聚性,避免跨应用的不必要依赖。
  • 过滤条件(System的name或uuid)直接对应System模型,查询入口更直观,后续维护时能快速定位到相关代码。
  • 如果后续需要扩展System相关的其他聚合数据,这个视图的位置也能保持代码结构的一致性。

2. 如何生成SPA所需的数据结构?

你倾向的「直接从数据库返回对应结构」是更高效的方案,同时结合DRF的序列化机制能兼顾可维护性,这里提供两种实践方案:

方案一:数据库层面构造目标结构(性能优先)

利用Django ORM的Prefetch和values()方法,直接从数据库查询出需要的字段组合,减少内存中的数据转换开销:

# systems/views.py
from rest_framework.response import Response
from rest_framework.views import APIView
from django.db.models import Prefetch
from .models import System

class SystemCameraConfigView(APIView):
    def get(self, request, system_uuid):
        # 预加载关联的Vision和Camera,避免N+1查询
        system = System.objects.prefetch_related(
            Prefetch('vision', queryset=Vision.objects.prefetch_related('camera'))
        ).get(uuid=system_uuid)
        
        # 直接从关联模型中提取所需字段
        camera_data = []
        for vision_module in system.vision.all():
            for camera in vision_module.camera.all():
                # 注意:这里假设Camera的name对应Hardware模型的name字段,根据你的实际模型调整
                camera_data.append({
                    "name": camera.hardware.name,
                    "module": str(vision_module.system_id)
                })
        
        return Response(camera_data)

方案二:自定义序列化器(可维护性优先)

如果后续需要扩展字段或添加验证逻辑,自定义序列化器会更灵活:

# systems/serializers.py
from rest_framework import serializers
from visions.models import Vision
from cameras.models import Camera

class CameraConfigSerializer(serializers.Serializer):
    name = serializers.CharField(source='hardware.name')
    module = serializers.CharField(source='vision.system_id')

# systems/views.py
from rest_framework.generics import RetrieveAPIView
from .models import System
from .serializers import CameraConfigSerializer

class SystemCameraConfigView(RetrieveAPIView):
    queryset = System.objects.prefetch_related('vision__camera')
    lookup_field = 'uuid'

    def retrieve(self, request, *args, **kwargs):
        system = self.get_object()
        # 收集所有关联的Camera数据并序列化
        cameras = []
        for vision in system.vision.all():
            cameras.extend(vision.camera.all())
        
        serializer = CameraConfigSerializer(cameras, many=True, context={'vision': vision})
        return Response(serializer.data)

3. 如何设计符合REST规范的URL?

/visions-configuration这种URL不符合REST的「资源导向」原则,因为它没有明确关联到System资源,建议采用层级化的资源路径:

  • 推荐URL:GET /systems/{system-uuid}/camera-configurations/
    • 清晰表达了「某个System下的相机配置数据」这一资源关系,客户端一看就能理解请求的上下文。
    • 如果需要更简洁的命名,也可以用/systems/{system-uuid}/cameras/,但加上-configurations更贴合你返回的「名称-模块对应关系」的业务场景。

这种设计既符合REST规范,也方便后续扩展其他System相关的子资源(比如/systems/{system-uuid}/vision-settings/)。

内容的提问来源于stack exchange,提问作者Kimor

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 20:27:48