diff --git a/apps/assets/api/platform.py b/apps/assets/api/platform.py index 4df9cb4a3..bce8505cf 100644 --- a/apps/assets/api/platform.py +++ b/apps/assets/api/platform.py @@ -1,3 +1,4 @@ +from django.db.models import Count from rest_framework import generics from rest_framework import serializers from rest_framework.decorators import action @@ -5,7 +6,7 @@ from rest_framework.response import Response from assets.const import AllTypes from assets.models import Platform, Node, Asset, PlatformProtocol -from assets.serializers import PlatformSerializer, PlatformProtocolSerializer +from assets.serializers import PlatformSerializer, PlatformProtocolSerializer, PlatformListSerializer from common.api import JMSModelViewSet from common.permissions import IsValidUser from common.serializers import GroupedChoiceSerializer @@ -17,6 +18,7 @@ class AssetPlatformViewSet(JMSModelViewSet): queryset = Platform.objects.all() serializer_classes = { 'default': PlatformSerializer, + 'list': PlatformListSerializer, 'categories': GroupedChoiceSerializer, } filterset_fields = ['name', 'category', 'type'] @@ -31,8 +33,8 @@ class AssetPlatformViewSet(JMSModelViewSet): def get_queryset(self): # 因为没有走分页逻辑,所以需要这里 prefetch - queryset = super().get_queryset().prefetch_related( - 'protocols', 'automation', 'labels', 'labels__label', + queryset = super().get_queryset().annotate(assets_amount=Count('assets')).prefetch_related( + 'protocols', 'automation', 'labels', 'labels__label' ) queryset = queryset.filter(type__in=AllTypes.get_types_values()) return queryset diff --git a/apps/assets/models/platform.py b/apps/assets/models/platform.py index 442579e9f..54664cb8a 100644 --- a/apps/assets/models/platform.py +++ b/apps/assets/models/platform.py @@ -111,6 +111,10 @@ class Platform(LabeledMixin, JMSBaseModel): def type_constraints(self): return AllTypes.get_constraints(self.category, self.type) + @lazyproperty + def assets_amount(self): + return self.assets.count() + @classmethod def default(cls): linux, created = cls.objects.get_or_create( diff --git a/apps/assets/serializers/platform.py b/apps/assets/serializers/platform.py index 3441ac6f4..b4d3207fd 100644 --- a/apps/assets/serializers/platform.py +++ b/apps/assets/serializers/platform.py @@ -1,18 +1,19 @@ -from django.db.models import QuerySet +from django.db.models import QuerySet, Count from django.utils.translation import gettext_lazy as _ from rest_framework import serializers from rest_framework.validators import UniqueValidator +from assets.models import Asset from common.serializers import ( WritableNestedModelSerializer, type_field_map, MethodSerializer, DictSerializer, create_serializer_class, ResourceLabelsMixin ) -from common.serializers.fields import LabeledChoiceField +from common.serializers.fields import LabeledChoiceField, ObjectRelatedField from common.utils import lazyproperty from ..const import Category, AllTypes, Protocol from ..models import Platform, PlatformProtocol, PlatformAutomation -__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer", "PlatformProtocolSerializer"] +__all__ = ["PlatformSerializer", "PlatformOpsMethodSerializer", "PlatformProtocolSerializer", "PlatformListSerializer"] class PlatformAutomationSerializer(serializers.ModelSerializer): @@ -179,6 +180,8 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): required=False, default="sudo", allow_null=True ) custom_fields = PlatformCustomField(label=_("Custom fields"), many=True, required=False) + assets = ObjectRelatedField(queryset=Asset.objects, many=True, required=False, label=_('Assets')) + assets_amount = serializers.IntegerField(label=_('Assets amount'), read_only=True) class Meta: model = Platform @@ -191,7 +194,8 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): 'internal', 'date_created', 'date_updated', 'created_by', 'updated_by' ] - fields = fields_small + [ + fields_m2m = ['assets', 'assets_amount'] + fields = fields_small + fields_m2m + [ "protocols", "domain_enabled", "su_enabled", "su_method", "automation", "comment", "custom_fields", "labels" ] + read_only_fields @@ -208,6 +212,7 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): "help_text": _("Assets can be connected using a zone gateway") }, "domain_default": {"label": _('Default Domain')}, + 'assets': {'required': False, 'label': _('Assets')}, } def __init__(self, *args, **kwargs): @@ -265,6 +270,11 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer): return automation +class PlatformListSerializer(PlatformSerializer): + class Meta(PlatformSerializer.Meta): + fields = list(set(PlatformSerializer.Meta.fields + ['assets_amount']) - {'assets'}) + + class PlatformOpsMethodSerializer(serializers.Serializer): id = serializers.CharField(read_only=True) name = serializers.CharField(max_length=50, label=_("Name"))