mirror of https://github.com/jumpserver/jumpserver
perf: 添加 JSONManyToManyFieldSerializer
parent
338ab5c634
commit
90090a7fc7
|
@ -2,7 +2,7 @@ from django.utils.translation import ugettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
from acls.models.base import ActionChoices
|
from acls.models.base import ActionChoices
|
||||||
from common.serializers.fields import LabeledChoiceField, ObjectRelatedField
|
from common.serializers.fields import JSONManyToManyField, ObjectRelatedField, LabeledChoiceField
|
||||||
from orgs.models import Organization
|
from orgs.models import Organization
|
||||||
from users.models import User
|
from users.models import User
|
||||||
|
|
||||||
|
@ -52,25 +52,9 @@ class ACLAccountsSerializer(serializers.Serializer):
|
||||||
|
|
||||||
|
|
||||||
class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
|
class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
|
||||||
users = ACLUsersSerializer(label=_('User'))
|
users = JSONManyToManyField(label=_('User'))
|
||||||
assets = ACLAssestsSerializer(label=_('Asset'))
|
assets = JSONManyToManyField(label=_('Asset'))
|
||||||
accounts = ACLAccountsSerializer(label=_('Account'))
|
accounts = JSONManyToManyField(label=_('Account'))
|
||||||
users_username_group = serializers.ListField(
|
|
||||||
source='users.username_group', read_only=True, child=serializers.CharField(),
|
|
||||||
label=_('User (username)')
|
|
||||||
)
|
|
||||||
assets_name_group = serializers.ListField(
|
|
||||||
source='assets.name_group', read_only=True, child=serializers.CharField(),
|
|
||||||
label=_('Asset (name)')
|
|
||||||
)
|
|
||||||
assets_address_group = serializers.ListField(
|
|
||||||
source='assets.address_group', read_only=True, child=serializers.CharField(),
|
|
||||||
label=_('Asset (address)')
|
|
||||||
)
|
|
||||||
accounts_username_group = serializers.ListField(
|
|
||||||
source='accounts.username_group', read_only=True, child=serializers.CharField(),
|
|
||||||
label=_('Account (username)')
|
|
||||||
)
|
|
||||||
reviewers = ObjectRelatedField(
|
reviewers = ObjectRelatedField(
|
||||||
queryset=User.objects, many=True, required=False, label=_('Reviewers')
|
queryset=User.objects, many=True, required=False, label=_('Reviewers')
|
||||||
)
|
)
|
||||||
|
@ -84,8 +68,6 @@ class BaseUserAssetAccountACLSerializerMixin(serializers.Serializer):
|
||||||
class Meta:
|
class Meta:
|
||||||
fields_mini = ["id", "name"]
|
fields_mini = ["id", "name"]
|
||||||
fields_small = fields_mini + [
|
fields_small = fields_mini + [
|
||||||
'users_username_group', 'assets_address_group', 'assets_name_group',
|
|
||||||
'accounts_username_group',
|
|
||||||
"users", "accounts", "assets", "is_active",
|
"users", "accounts", "assets", "is_active",
|
||||||
"date_created", "date_updated", "priority",
|
"date_created", "date_updated", "priority",
|
||||||
"action", "comment", "created_by", "org_id",
|
"action", "comment", "created_by", "org_id",
|
||||||
|
|
|
@ -429,29 +429,29 @@ class JSONManyToManyField(models.JSONField):
|
||||||
return name, path, args, kwargs
|
return name, path, args, kwargs
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _check_value(val):
|
def check_value(val):
|
||||||
if not val:
|
if not val:
|
||||||
return val
|
return val
|
||||||
e = ValueError(
|
e = ValueError(_(
|
||||||
'Invalid JSON data for JSONManyToManyField, should be like '
|
"Invalid JSON data for JSONManyToManyField, should be like "
|
||||||
'{"type": "all"} or {"type": "ids", "ids": []} '
|
"{'type': 'all'} or {'type': 'ids', 'ids': []} "
|
||||||
'or {"type": "attrs", "attrs": [{"name": "ip", "match": "exact", "value": "value"}'
|
"or {'type': 'attrs', 'attrs': [{'name': 'ip', 'match': 'exact', 'value': 'value'}"
|
||||||
)
|
))
|
||||||
if not isinstance(val, dict):
|
if not isinstance(val, dict):
|
||||||
raise e
|
raise e
|
||||||
if val["type"] not in ["all", "ids", "attrs"]:
|
if val["type"] not in ["all", "ids", "attrs"]:
|
||||||
raise e
|
raise ValueError(_('Invalid type, should be "all", "ids" or "attrs"'))
|
||||||
if val["type"] == "ids":
|
if val["type"] == "ids":
|
||||||
if not isinstance(val["ids"], list):
|
if not isinstance(val["ids"], list):
|
||||||
raise e
|
raise ValueError(_("Invalid ids for ids, should be a list"))
|
||||||
elif val["type"] == "attrs":
|
elif val["type"] == "attrs":
|
||||||
if not isinstance(val["attrs"], list):
|
if not isinstance(val["attrs"], list):
|
||||||
raise e
|
raise ValueError(_("Invalid attrs, should be a list of dict"))
|
||||||
for attr in val["attrs"]:
|
for attr in val["attrs"]:
|
||||||
if not isinstance(attr, dict):
|
if not isinstance(attr, dict):
|
||||||
raise e
|
raise ValueError(_("Invalid attrs, should be a list of dict"))
|
||||||
if 'name' not in attr or 'value' not in attr:
|
if 'name' not in attr or 'value' not in attr:
|
||||||
raise e
|
raise ValueError(_("Invalid attrs, should be has name and value"))
|
||||||
|
|
||||||
def get_db_prep_value(self, value, connection, prepared=False):
|
def get_db_prep_value(self, value, connection, prepared=False):
|
||||||
return self.get_prep_value(value)
|
return self.get_prep_value(value)
|
||||||
|
@ -461,7 +461,7 @@ class JSONManyToManyField(models.JSONField):
|
||||||
return None
|
return None
|
||||||
if isinstance(value, RelatedManager):
|
if isinstance(value, RelatedManager):
|
||||||
value = value.value
|
value = value.value
|
||||||
self._check_value(value)
|
self.check_value(value)
|
||||||
return json.dumps(value)
|
return json.dumps(value)
|
||||||
|
|
||||||
def validate(self, value, model_instance):
|
def validate(self, value, model_instance):
|
||||||
|
|
|
@ -7,7 +7,7 @@ from django.utils.translation import gettext_lazy as _
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
from rest_framework.fields import ChoiceField, empty
|
from rest_framework.fields import ChoiceField, empty
|
||||||
|
|
||||||
from common.db.fields import TreeChoices
|
from common.db.fields import TreeChoices, JSONManyToManyField as ModelJSONManyToManyField
|
||||||
from common.local import add_encrypted_field_set
|
from common.local import add_encrypted_field_set
|
||||||
from common.utils import decrypt_password
|
from common.utils import decrypt_password
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ __all__ = [
|
||||||
"TreeChoicesField",
|
"TreeChoicesField",
|
||||||
"LabeledMultipleChoiceField",
|
"LabeledMultipleChoiceField",
|
||||||
"PhoneField",
|
"PhoneField",
|
||||||
|
"JSONManyToManyField"
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
@ -216,3 +217,17 @@ class PhoneField(serializers.CharField):
|
||||||
phone = phonenumbers.parse(value, 'CN')
|
phone = phonenumbers.parse(value, 'CN')
|
||||||
value = {'code': '+%s' % phone.country_code, 'phone': phone.national_number}
|
value = {'code': '+%s' % phone.country_code, 'phone': phone.national_number}
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
class JSONManyToManyField(serializers.JSONField):
|
||||||
|
def to_representation(self, value):
|
||||||
|
return value.value
|
||||||
|
|
||||||
|
def to_internal_value(self, data):
|
||||||
|
if not data:
|
||||||
|
data = {}
|
||||||
|
try:
|
||||||
|
ModelJSONManyToManyField.check_value(data)
|
||||||
|
except ValueError as e:
|
||||||
|
raise serializers.ValidationError(e)
|
||||||
|
return super().to_internal_value(data)
|
||||||
|
|
Loading…
Reference in New Issue