mirror of
https://github.com/jumpserver/jumpserver.git
synced 2025-04-28 19:34:53 +00:00
perf: 优化标签绑定,仅绑定到资产上
This commit is contained in:
parent
eb5a53b91b
commit
15ac81a422
@ -29,8 +29,9 @@ class AssetPlatformViewSet(JMSModelViewSet):
|
|||||||
}
|
}
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
|
# 因为没有走分页逻辑,所以需要这里 prefetch
|
||||||
queryset = super().get_queryset().prefetch_related(
|
queryset = super().get_queryset().prefetch_related(
|
||||||
'protocols', 'automation'
|
'protocols', 'automation', 'labels', 'labels__label',
|
||||||
)
|
)
|
||||||
queryset = queryset.filter(type__in=AllTypes.get_types_values())
|
queryset = queryset.filter(type__in=AllTypes.get_types_values())
|
||||||
return queryset
|
return queryset
|
||||||
|
@ -100,7 +100,10 @@ class AssetAccountSerializer(AccountSerializer):
|
|||||||
class Meta(AccountSerializer.Meta):
|
class Meta(AccountSerializer.Meta):
|
||||||
fields = [
|
fields = [
|
||||||
f for f in AccountSerializer.Meta.fields
|
f for f in AccountSerializer.Meta.fields
|
||||||
if f not in ['spec_info']
|
if f not in [
|
||||||
|
'spec_info', 'connectivity', 'labels', 'created_by',
|
||||||
|
'date_update', 'date_created'
|
||||||
|
]
|
||||||
]
|
]
|
||||||
extra_kwargs = {
|
extra_kwargs = {
|
||||||
**AccountSerializer.Meta.extra_kwargs,
|
**AccountSerializer.Meta.extra_kwargs,
|
||||||
@ -375,7 +378,6 @@ class AssetSerializer(BulkOrgResourceModelSerializer, ResourceLabelsMixin, Writa
|
|||||||
|
|
||||||
|
|
||||||
class DetailMixin(serializers.Serializer):
|
class DetailMixin(serializers.Serializer):
|
||||||
accounts = AssetAccountSerializer(many=True, required=False, label=_('Accounts'))
|
|
||||||
spec_info = MethodSerializer(label=_('Spec info'), read_only=True)
|
spec_info = MethodSerializer(label=_('Spec info'), read_only=True)
|
||||||
gathered_info = MethodSerializer(label=_('Gathered info'), read_only=True)
|
gathered_info = MethodSerializer(label=_('Gathered info'), read_only=True)
|
||||||
auto_config = serializers.DictField(read_only=True, label=_('Auto info'))
|
auto_config = serializers.DictField(read_only=True, label=_('Auto info'))
|
||||||
@ -390,8 +392,7 @@ class DetailMixin(serializers.Serializer):
|
|||||||
def get_field_names(self, declared_fields, info):
|
def get_field_names(self, declared_fields, info):
|
||||||
names = super().get_field_names(declared_fields, info)
|
names = super().get_field_names(declared_fields, info)
|
||||||
names.extend([
|
names.extend([
|
||||||
'accounts', 'gathered_info', 'spec_info',
|
'gathered_info', 'spec_info', 'auto_config',
|
||||||
'auto_config',
|
|
||||||
])
|
])
|
||||||
return names
|
return names
|
||||||
|
|
||||||
|
@ -200,12 +200,6 @@ class PlatformSerializer(ResourceLabelsMixin, WritableNestedModelSerializer):
|
|||||||
constraints = AllTypes.get_constraints(category, tp)
|
constraints = AllTypes.get_constraints(category, tp)
|
||||||
return constraints
|
return constraints
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def setup_eager_loading(cls, queryset):
|
|
||||||
queryset = queryset.prefetch_related('protocols', 'automation') \
|
|
||||||
.prefetch_related('labels', 'labels__label')
|
|
||||||
return queryset
|
|
||||||
|
|
||||||
def validate_protocols(self, protocols):
|
def validate_protocols(self, protocols):
|
||||||
if not protocols:
|
if not protocols:
|
||||||
raise serializers.ValidationError(_("Protocols is required"))
|
raise serializers.ValidationError(_("Protocols is required"))
|
||||||
|
@ -219,10 +219,10 @@ class LabelFilterBackend(filters.BaseFilterBackend):
|
|||||||
if not hasattr(queryset, 'model'):
|
if not hasattr(queryset, 'model'):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
if not hasattr(queryset.model, 'labels'):
|
if not hasattr(queryset.model, 'label_model'):
|
||||||
return queryset
|
return queryset
|
||||||
|
|
||||||
model = queryset.model
|
model = queryset.model.label_model()
|
||||||
labeled_resource_cls = model._labels.field.related_model
|
labeled_resource_cls = model._labels.field.related_model
|
||||||
app_label = model._meta.app_label
|
app_label = model._meta.app_label
|
||||||
model_name = model._meta.model_name
|
model_name = model._meta.model_name
|
||||||
|
@ -69,7 +69,7 @@ def digest_sql_query():
|
|||||||
|
|
||||||
for query in queries:
|
for query in queries:
|
||||||
sql = query['sql']
|
sql = query['sql']
|
||||||
print(" # {}: {}".format(query['time'], sql))
|
print(" # {}: {}".format(query['time'], sql[:1000]))
|
||||||
if len(queries) < 3:
|
if len(queries) < 3:
|
||||||
continue
|
continue
|
||||||
print("- Table: {}".format(table_name))
|
print("- Table: {}".format(table_name))
|
||||||
|
@ -73,7 +73,7 @@ class LabelContentTypeResourceViewSet(JMSModelViewSet):
|
|||||||
queryset = model.objects.all()
|
queryset = model.objects.all()
|
||||||
if bound == '1':
|
if bound == '1':
|
||||||
queryset = queryset.filter(id__in=list(res_ids))
|
queryset = queryset.filter(id__in=list(res_ids))
|
||||||
elif bound == '0':
|
else:
|
||||||
queryset = queryset.exclude(id__in=list(res_ids))
|
queryset = queryset.exclude(id__in=list(res_ids))
|
||||||
keyword = self.request.query_params.get('search')
|
keyword = self.request.query_params.get('search')
|
||||||
if keyword:
|
if keyword:
|
||||||
@ -90,9 +90,10 @@ class LabelContentTypeResourceViewSet(JMSModelViewSet):
|
|||||||
LabeledResource.objects \
|
LabeledResource.objects \
|
||||||
.filter(res_type=content_type, label=label) \
|
.filter(res_type=content_type, label=label) \
|
||||||
.exclude(res_id__in=res_ids).delete()
|
.exclude(res_id__in=res_ids).delete()
|
||||||
resources = []
|
resources = [
|
||||||
for res_id in res_ids:
|
LabeledResource(res_type=content_type, res_id=res_id, label=label, org_id=current_org.id)
|
||||||
resources.append(LabeledResource(res_type=content_type, res_id=res_id, label=label, org_id=current_org.id))
|
for res_id in res_ids
|
||||||
|
]
|
||||||
LabeledResource.objects.bulk_create(resources, ignore_conflicts=True)
|
LabeledResource.objects.bulk_create(resources, ignore_conflicts=True)
|
||||||
return Response({"total": len(res_ids)})
|
return Response({"total": len(res_ids)})
|
||||||
|
|
||||||
@ -129,14 +130,21 @@ class LabeledResourceViewSet(OrgBulkModelViewSet):
|
|||||||
}
|
}
|
||||||
ordering_fields = ('res_type', 'date_created')
|
ordering_fields = ('res_type', 'date_created')
|
||||||
|
|
||||||
# Todo: 这里需要优化,查询 sql 太多
|
|
||||||
def filter_search(self, queryset):
|
def filter_search(self, queryset):
|
||||||
keyword = self.request.query_params.get('search')
|
keyword = self.request.query_params.get('search')
|
||||||
if not keyword:
|
if not keyword:
|
||||||
return queryset
|
return queryset
|
||||||
|
keyword = keyword.strip().lower()
|
||||||
matched = []
|
matched = []
|
||||||
for instance in queryset:
|
offset = 0
|
||||||
if keyword.lower() in str(instance.resource).lower():
|
limit = 10000
|
||||||
|
while True:
|
||||||
|
page = queryset[offset:offset + limit]
|
||||||
|
if not page:
|
||||||
|
break
|
||||||
|
offset += limit
|
||||||
|
for instance in page:
|
||||||
|
if keyword in str(instance.resource).lower():
|
||||||
matched.append(instance.id)
|
matched.append(instance.id)
|
||||||
return queryset.filter(id__in=matched)
|
return queryset.filter(id__in=matched)
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
from django.contrib.contenttypes.fields import GenericRelation
|
from django.contrib.contenttypes.fields import GenericRelation
|
||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.db.models import OneToOneField
|
||||||
|
|
||||||
from .models import LabeledResource
|
from .models import LabeledResource
|
||||||
|
|
||||||
@ -12,10 +13,25 @@ class LabeledMixin(models.Model):
|
|||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def label_model(cls):
|
||||||
|
pk_field = cls._meta.pk
|
||||||
|
model = cls
|
||||||
|
if isinstance(pk_field, OneToOneField):
|
||||||
|
model = pk_field.related_model
|
||||||
|
return model
|
||||||
|
|
||||||
|
@property
|
||||||
|
def real(self):
|
||||||
|
pk_field = self._meta.pk
|
||||||
|
if isinstance(pk_field, OneToOneField):
|
||||||
|
return getattr(self, pk_field.name)
|
||||||
|
return self
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def labels(self):
|
def labels(self):
|
||||||
return self._labels
|
return self.real._labels
|
||||||
|
|
||||||
@labels.setter
|
@labels.setter
|
||||||
def labels(self, value):
|
def labels(self, value):
|
||||||
self._labels.set(value, bulk=False)
|
self.real._labels.set(value, bulk=False)
|
||||||
|
Loading…
Reference in New Issue
Block a user