Unverified Commit b4498f22 authored by BaiJiangJie's avatar BaiJiangJie Committed by GitHub

[Update] 修改 RemoteApp 前端 Form 渲染逻辑 (#3523)

* [Update] 修改 RemoteApp 前端 Form 渲染逻辑

* [Update] RemoteApp 表单添加默认值
parent b2932803
...@@ -12,29 +12,6 @@ REMOTE_APP_TYPE_MYSQL_WORKBENCH = 'mysql_workbench' ...@@ -12,29 +12,6 @@ REMOTE_APP_TYPE_MYSQL_WORKBENCH = 'mysql_workbench'
REMOTE_APP_TYPE_VMWARE_CLIENT = 'vmware_client' REMOTE_APP_TYPE_VMWARE_CLIENT = 'vmware_client'
REMOTE_APP_TYPE_CUSTOM = 'custom' REMOTE_APP_TYPE_CUSTOM = 'custom'
REMOTE_APP_TYPE_CHOICES = (
(
_('Browser'),
(
(REMOTE_APP_TYPE_CHROME, 'Chrome'),
)
),
(
_('Database tools'),
(
(REMOTE_APP_TYPE_MYSQL_WORKBENCH, 'MySQL Workbench'),
)
),
(
_('Virtualization tools'),
(
(REMOTE_APP_TYPE_VMWARE_CLIENT, 'vSphere Client'),
)
),
(REMOTE_APP_TYPE_CUSTOM, _('Custom')),
)
# Fields attribute write_only default => False # Fields attribute write_only default => False
REMOTE_APP_TYPE_CHROME_FIELDS = [ REMOTE_APP_TYPE_CHROME_FIELDS = [
...@@ -60,9 +37,16 @@ REMOTE_APP_TYPE_CUSTOM_FIELDS = [ ...@@ -60,9 +37,16 @@ REMOTE_APP_TYPE_CUSTOM_FIELDS = [
{'name': 'custom_password', 'write_only': True} {'name': 'custom_password', 'write_only': True}
] ]
REMOTE_APP_TYPE_MAP_FIELDS = { REMOTE_APP_TYPE_FIELDS_MAP = {
REMOTE_APP_TYPE_CHROME: REMOTE_APP_TYPE_CHROME_FIELDS, REMOTE_APP_TYPE_CHROME: REMOTE_APP_TYPE_CHROME_FIELDS,
REMOTE_APP_TYPE_MYSQL_WORKBENCH: REMOTE_APP_TYPE_MYSQL_WORKBENCH_FIELDS, REMOTE_APP_TYPE_MYSQL_WORKBENCH: REMOTE_APP_TYPE_MYSQL_WORKBENCH_FIELDS,
REMOTE_APP_TYPE_VMWARE_CLIENT: REMOTE_APP_TYPE_VMWARE_CLIENT_FIELDS, REMOTE_APP_TYPE_VMWARE_CLIENT: REMOTE_APP_TYPE_VMWARE_CLIENT_FIELDS,
REMOTE_APP_TYPE_CUSTOM: REMOTE_APP_TYPE_CUSTOM_FIELDS REMOTE_APP_TYPE_CUSTOM: REMOTE_APP_TYPE_CUSTOM_FIELDS
} }
REMOTE_APP_TYPE_CHOICES = (
(REMOTE_APP_TYPE_CHROME, 'Chrome'),
(REMOTE_APP_TYPE_MYSQL_WORKBENCH, 'MySQL Workbench'),
(REMOTE_APP_TYPE_VMWARE_CLIENT, 'vSphere Client'),
(REMOTE_APP_TYPE_CUSTOM, _('Custom')),
)
...@@ -5,18 +5,52 @@ from django.utils.translation import ugettext as _ ...@@ -5,18 +5,52 @@ from django.utils.translation import ugettext as _
from django import forms from django import forms
from orgs.mixins.forms import OrgModelForm from orgs.mixins.forms import OrgModelForm
from assets.models import SystemUser
from ..models import RemoteApp from ..models import RemoteApp
from .. import const
__all__ = [ __all__ = [
'RemoteAppCreateUpdateForm', 'RemoteAppChromeForm', 'RemoteAppMySQLWorkbenchForm',
'RemoteAppVMwareForm', 'RemoteAppCustomForm'
] ]
class RemoteAppTypeChromeForm(forms.ModelForm): class BaseRemoteAppForm(OrgModelForm):
default_initial_data = {}
def __init__(self, *args, **kwargs):
# 过滤RDP资产和系统用户
super().__init__(*args, **kwargs)
field_asset = self.fields['asset']
field_asset.queryset = field_asset.queryset.has_protocol('rdp')
self.fields['type'].widget.attrs['disabled'] = True
self.fields.move_to_end('comment')
self.initial_default()
def initial_default(self):
for name, value in self.default_initial_data.items():
field = self.fields.get(name)
if not field:
continue
field.initial = value
class Meta:
model = RemoteApp
fields = [
'name', 'asset', 'type', 'path', 'comment'
]
widgets = {
'asset': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Asset')
}),
}
class RemoteAppChromeForm(BaseRemoteAppForm):
default_initial_data = {
'path': r'C:\Program Files (x86)\Google\Chrome\Application\chrome.exe'
}
chrome_target = forms.CharField( chrome_target = forms.CharField(
max_length=128, label=_('Target URL'), required=False max_length=128, label=_('Target URL'), required=False
) )
...@@ -29,7 +63,12 @@ class RemoteAppTypeChromeForm(forms.ModelForm): ...@@ -29,7 +63,12 @@ class RemoteAppTypeChromeForm(forms.ModelForm):
) )
class RemoteAppTypeMySQLWorkbenchForm(forms.ModelForm): class RemoteAppMySQLWorkbenchForm(BaseRemoteAppForm):
default_initial_data = {
'path': r'C:\Program Files\MySQL\MySQL Workbench 8.0 CE'
r'\MySQLWorkbench.exe'
}
mysql_workbench_ip = forms.CharField( mysql_workbench_ip = forms.CharField(
max_length=128, label=_('Database IP'), required=False max_length=128, label=_('Database IP'), required=False
) )
...@@ -45,7 +84,12 @@ class RemoteAppTypeMySQLWorkbenchForm(forms.ModelForm): ...@@ -45,7 +84,12 @@ class RemoteAppTypeMySQLWorkbenchForm(forms.ModelForm):
) )
class RemoteAppTypeVMwareForm(forms.ModelForm): class RemoteAppVMwareForm(BaseRemoteAppForm):
default_initial_data = {
'path': r'C:\Program Files (x86)\VMware\Infrastructure'
r'\Virtual Infrastructure Client\Launcher\VpxClient.exe'
}
vmware_target = forms.CharField( vmware_target = forms.CharField(
max_length=128, label=_('Target address'), required=False max_length=128, label=_('Target address'), required=False
) )
...@@ -58,7 +102,8 @@ class RemoteAppTypeVMwareForm(forms.ModelForm): ...@@ -58,7 +102,8 @@ class RemoteAppTypeVMwareForm(forms.ModelForm):
) )
class RemoteAppTypeCustomForm(forms.ModelForm): class RemoteAppCustomForm(BaseRemoteAppForm):
custom_cmdline = forms.CharField( custom_cmdline = forms.CharField(
max_length=128, label=_('Operating parameter'), required=False max_length=128, label=_('Operating parameter'), required=False
) )
...@@ -73,51 +118,3 @@ class RemoteAppTypeCustomForm(forms.ModelForm): ...@@ -73,51 +118,3 @@ class RemoteAppTypeCustomForm(forms.ModelForm):
max_length=128, label=_('Login password'), required=False max_length=128, label=_('Login password'), required=False
) )
class RemoteAppTypeForms(
RemoteAppTypeChromeForm,
RemoteAppTypeMySQLWorkbenchForm,
RemoteAppTypeVMwareForm,
RemoteAppTypeCustomForm
):
pass
class RemoteAppCreateUpdateForm(RemoteAppTypeForms, OrgModelForm):
def __init__(self, *args, **kwargs):
# 过滤RDP资产和系统用户
super().__init__(*args, **kwargs)
field_asset = self.fields['asset']
field_asset.queryset = field_asset.queryset.has_protocol('rdp')
class Meta:
model = RemoteApp
fields = [
'name', 'asset', 'type', 'path', 'comment'
]
widgets = {
'asset': forms.Select(attrs={
'class': 'select2', 'data-placeholder': _('Asset')
}),
}
def _clean_params(self):
app_type = self.data.get('type')
fields = const.REMOTE_APP_TYPE_MAP_FIELDS.get(app_type, [])
params = {}
for field in fields:
name = field['name']
value = self.cleaned_data[name]
params.update({name: value})
return params
def _save_params(self, instance):
params = self._clean_params()
instance.params = params
instance.save()
return instance
def save(self, commit=True):
instance = super().save(commit=commit)
instance = self._save_params(instance)
return instance
...@@ -62,7 +62,7 @@ class RemoteApp(OrgModelMixin): ...@@ -62,7 +62,7 @@ class RemoteApp(OrgModelMixin):
_parameters.append(self.type) _parameters.append(self.type)
path = '\"%s\"' % self.path path = '\"%s\"' % self.path
_parameters.append(path) _parameters.append(path)
for field in const.REMOTE_APP_TYPE_MAP_FIELDS[self.type]: for field in const.REMOTE_APP_TYPE_FIELDS_MAP[self.type]:
value = self.params.get(field['name']) value = self.params.get(field['name'])
if value is None: if value is None:
continue continue
......
# coding: utf-8 # coding: utf-8
# #
import copy
from rest_framework import serializers from rest_framework import serializers
from common.serializers import AdaptedBulkListSerializer from common.serializers import AdaptedBulkListSerializer
...@@ -18,26 +18,53 @@ __all__ = [ ...@@ -18,26 +18,53 @@ __all__ = [
class RemoteAppParamsDictField(CustomMetaDictField): class RemoteAppParamsDictField(CustomMetaDictField):
type_map_fields = const.REMOTE_APP_TYPE_MAP_FIELDS type_fields_map = const.REMOTE_APP_TYPE_FIELDS_MAP
default_type = const.REMOTE_APP_TYPE_CHROME default_type = const.REMOTE_APP_TYPE_CHROME
convert_key_remove_type_prefix = False
convert_key_to_upper = False
class RemoteAppSerializer(BulkOrgResourceModelSerializer): class RemoteAppSerializer(BulkOrgResourceModelSerializer):
params = RemoteAppParamsDictField() params = RemoteAppParamsDictField()
type_fields_map = const.REMOTE_APP_TYPE_FIELDS_MAP
class Meta: class Meta:
model = RemoteApp model = RemoteApp
list_serializer_class = AdaptedBulkListSerializer list_serializer_class = AdaptedBulkListSerializer
fields = [ fields = [
'id', 'name', 'asset', 'type', 'path', 'params', 'id', 'name', 'asset', 'asset_info', 'type', 'get_type_display',
'comment', 'created_by', 'date_created', 'asset_info', 'path', 'params', 'date_created', 'created_by', 'comment',
'get_type_display',
] ]
read_only_fields = [ read_only_fields = [
'created_by', 'date_created', 'asset_info', 'created_by', 'date_created', 'asset_info',
'get_type_display' 'get_type_display'
] ]
def process_params(self, instance, validated_data):
new_params = copy.deepcopy(validated_data.get('params', {}))
tp = validated_data.get('type', '')
if tp != instance.type:
return new_params
old_params = instance.params
fields = self.type_fields_map.get(instance.type, [])
for field in fields:
if not field.get('write_only', False):
continue
field_name = field['name']
new_value = new_params.get(field_name, '')
old_value = old_params.get(field_name, '')
field_value = new_value if new_value else old_value
new_params[field_name] = field_value
return new_params
def update(self, instance, validated_data):
params = self.process_params(instance, validated_data)
validated_data['params'] = params
return super().update(instance, validated_data)
class RemoteAppConnectionInfoSerializer(serializers.ModelSerializer): class RemoteAppConnectionInfoSerializer(serializers.ModelSerializer):
parameter_remote_app = serializers.SerializerMethodField() parameter_remote_app = serializers.SerializerMethodField()
......
...@@ -4,51 +4,8 @@ ...@@ -4,51 +4,8 @@
{% load i18n %} {% load i18n %}
{% block form %} {% block form %}
<form id="appForm" method="post" class="form-horizontal"> <form id="RemoteAppForm" method="post" class="form-horizontal">
{% if form.non_field_errors %} {% bootstrap_form form layout="horizontal" %}
<div class="alert alert-danger">
{{ form.non_field_errors }}
</div>
{% endif %}
{% csrf_token %}
{% bootstrap_field form.name layout="horizontal" %}
{% bootstrap_field form.asset layout="horizontal" %}
{% bootstrap_field form.type layout="horizontal" %}
{% bootstrap_field form.path layout="horizontal" %}
<div class="hr-line-dashed"></div>
{# chrome #}
<div class="chrome-fields hidden">
{% bootstrap_field form.chrome_target layout="horizontal" %}
{% bootstrap_field form.chrome_username layout="horizontal" %}
{% bootstrap_field form.chrome_password layout="horizontal" %}
</div>
{# mysql workbench #}
<div class="mysql_workbench-fields hidden">
{% bootstrap_field form.mysql_workbench_ip layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_name layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_username layout="horizontal" %}
{% bootstrap_field form.mysql_workbench_password layout="horizontal" %}
</div>
{# vmware #}
<div class="vmware_client-fields hidden">
{% bootstrap_field form.vmware_target layout="horizontal" %}
{% bootstrap_field form.vmware_username layout="horizontal" %}
{% bootstrap_field form.vmware_password layout="horizontal" %}
</div>
{# custom #}
<div class="custom-fields hidden">
{% bootstrap_field form.custom_cmdline layout="horizontal" %}
{% bootstrap_field form.custom_target layout="horizontal" %}
{% bootstrap_field form.custom_username layout="horizontal" %}
{% bootstrap_field form.custom_password layout="horizontal" %}
</div>
{% bootstrap_field form.comment layout="horizontal" %}
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
...@@ -57,93 +14,49 @@ ...@@ -57,93 +14,49 @@
<button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button> <button id="submit_button" class="btn btn-primary" type="submit">{% trans 'Submit' %}</button>
</div> </div>
</div> </div>
</form> </form>
{% endblock %} {% endblock %}
{% block custom_foot_js %} {% block custom_foot_js %}
<script type="text/javascript"> <script type="text/javascript">
var app_type_id = '#' + '{{ form.type.id_for_label }}'; var app_type_id = '#' + '{{ form.type.id_for_label }}';
var app_path_id = '#' + '{{ form.path.id_for_label }}';
var all_type_fields = [ function getFormDataType(){
'.chrome-fields',
'.mysql_workbench-fields',
'.vmware_client-fields',
'.custom-fields'
];
var app_type_map_default_fields_value = {
'chrome': {
'app_path': 'C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe'
},
'mysql_workbench': {
'app_path': 'C:\\Program Files\\MySQL\\MySQL Workbench 8.0 CE\\MySQLWorkbench.exe'
},
'vmware_client': {
'app_path': 'C:\\Program Files (x86)\\VMware\\Infrastructure\\Virtual Infrastructure Client\\Launcher\\VpxClient.exe'
},
'custom': {'app_path': ''}
};
function getAppType(){
return $(app_type_id+ " option:selected").val(); return $(app_type_id+ " option:selected").val();
} }
function initialDefaultValue(){ function constructFormDataParams(data){
var app_type = getAppType();
var app_path = $(app_path_id).val();
if(app_path){
app_type_map_default_fields_value[app_type]['app_path'] = app_path
}
}
function setDefaultValue(){
// 设置类型相关字段的默认值
var app_type = getAppType();
var app_path = app_type_map_default_fields_value[app_type]['app_path'];
$(app_path_id).val(app_path)
}
function hiddenFields(){
var app_type = getAppType();
$.each(all_type_fields, function(index, value){
$(value).addClass('hidden')
});
$('.' + app_type + '-fields').removeClass('hidden');
}
function constructParams(data) {
var typeList = ['chrome', 'mysql_workbench', 'vmware_client', 'custom'];
var params = {}; var params = {};
$.each(typeList, function(index, value){ var type =data.type;
if (data.type === value){
for (var k in data){ for (var k in data){
if (k.startsWith(value)){ if (k.startsWith(type)){
params[k] = data[k] params[k] = data[k];
delete data[k]
} }
} }
} return params
}); }
return params; function getFormData(form){
var data = form.serializeObject();
data['type'] = getFormDataType();
data['params'] = constructFormDataParams(data);
return data
} }
$(document).ready(function () { $(document).ready(function () {
$('.select2').select2({ $('.select2').select2({
closeOnSelect: true closeOnSelect: true
}); });
initialDefaultValue(); }).on("submit", "form", function (evt) {
hiddenFields();
setDefaultValue();
})
.on('change', app_type_id, function(){
hiddenFields();
setDefaultValue();
})
.on("submit", "form", function (evt) {
evt.preventDefault(); evt.preventDefault();
var the_url = '{% url "api-applications:remote-app-list" %}'; var the_url = '{% url "api-applications:remote-app-list" %}';
var redirect_to = '{% url "applications:remote-app-list" %}'; var redirect_to = '{% url "applications:remote-app-list" %}';
var method = "POST"; var method = "POST";
{% if type == "update" %} {% if api_action == "update" %}
the_url = '{% url "api-applications:remote-app-detail" object.id %}'; the_url = '{% url "api-applications:remote-app-detail" object.id %}';
method = "PUT"; method = "PUT";
{% endif %} {% endif %}
var form = $("form"); var form = $("form");
var data = form.serializeObject(); var data = getFormData(form);
data["params"] = constructParams(data);
var props = { var props = {
url: the_url, url: the_url,
data: data, data: data,
......
...@@ -6,8 +6,16 @@ ...@@ -6,8 +6,16 @@
{% endblock %} {% endblock %}
{% block table_search %}{% endblock %} {% block table_search %}{% endblock %}
{% block table_container %} {% block table_container %}
<div class="uc pull-left m-r-5"> <div class="btn-group uc pull-left m-r-5">
<a href="{% url 'applications:remote-app-create' %}" class="btn btn-sm btn-primary"> {% trans "Create RemoteApp" %} </a> <button class="btn btn-sm btn-primary">
{% trans "Create RemoteApp" %}
</button>
<button data-toggle="dropdown" class="btn btn-primary btn-sm dropdown-toggle"><span class="caret"></span></button>
<ul class="dropdown-menu">
{% for key, value in type_choices %}
<li><a class="" href="{% url 'applications:remote-app-create' %}?type={{ key }}">{{ value }}</a></li>
{% endfor %}
</ul>
</div> </div>
<table class="table table-striped table-bordered table-hover " id="remote_app_list_table" > <table class="table table-striped table-bordered table-hover " id="remote_app_list_table" >
<thead> <thead>
......
# coding: utf-8 # coding: utf-8
# #
from django.http import Http404
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.views.generic import TemplateView from django.views.generic import TemplateView
from django.views.generic.edit import CreateView, UpdateView from django.views.generic.edit import CreateView, UpdateView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from django.contrib.messages.views import SuccessMessageMixin
from django.urls import reverse_lazy
from common.permissions import PermissionsMixin, IsOrgAdmin, IsValidUser from common.permissions import PermissionsMixin, IsOrgAdmin, IsValidUser
from common.const import create_success_msg, update_success_msg
from ..models import RemoteApp from ..models import RemoteApp
from .. import forms from .. import forms, const
__all__ = [ __all__ = [
...@@ -30,53 +27,79 @@ class RemoteAppListView(PermissionsMixin, TemplateView): ...@@ -30,53 +27,79 @@ class RemoteAppListView(PermissionsMixin, TemplateView):
context = { context = {
'app': _('Applications'), 'app': _('Applications'),
'action': _('RemoteApp list'), 'action': _('RemoteApp list'),
'type_choices': const.REMOTE_APP_TYPE_CHOICES,
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
class RemoteAppCreateView(PermissionsMixin, SuccessMessageMixin, CreateView): class BaseRemoteAppCreateUpdateView:
template_name = 'applications/remote_app_create_update.html' template_name = 'applications/remote_app_create_update.html'
model = RemoteApp model = RemoteApp
form_class = forms.RemoteAppCreateUpdateForm
success_url = reverse_lazy('applications:remote-app-list')
permission_classes = [IsOrgAdmin] permission_classes = [IsOrgAdmin]
default_type = const.REMOTE_APP_TYPE_CHROME
form_class = forms.RemoteAppChromeForm
form_class_choices = {
const.REMOTE_APP_TYPE_CHROME: forms.RemoteAppChromeForm,
const.REMOTE_APP_TYPE_MYSQL_WORKBENCH: forms.RemoteAppMySQLWorkbenchForm,
const.REMOTE_APP_TYPE_VMWARE_CLIENT: forms.RemoteAppVMwareForm,
const.REMOTE_APP_TYPE_CUSTOM: forms.RemoteAppCustomForm
}
def get_initial(self):
return {'type': self.get_type()}
def get_type(self):
return self.default_type
def get_form_class(self):
tp = self.get_type()
form_class = self.form_class_choices.get(tp)
if not form_class:
raise Http404()
return form_class
class RemoteAppCreateView(BaseRemoteAppCreateUpdateView,
PermissionsMixin, CreateView):
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Applications'), 'app': _('Applications'),
'action': _('Create RemoteApp'), 'action': _('Create RemoteApp'),
'type': 'create' 'api_action': 'create'
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
def get_success_message(self, cleaned_data): def get_type(self):
return create_success_msg % ({'name': cleaned_data['name']}) tp = self.request.GET.get("type")
if tp:
return tp.lower()
return super().get_type()
class RemoteAppUpdateView(PermissionsMixin, SuccessMessageMixin, UpdateView): class RemoteAppUpdateView(BaseRemoteAppCreateUpdateView,
template_name = 'applications/remote_app_create_update.html' PermissionsMixin, UpdateView):
model = RemoteApp
form_class = forms.RemoteAppCreateUpdateForm
success_url = reverse_lazy('applications:remote-app-list')
permission_classes = [IsOrgAdmin]
def get_initial(self): def get_initial(self):
return {k: v for k, v in self.object.params.items()} initial_data = super().get_initial()
params = {k: v for k, v in self.object.params.items()}
initial_data.update(params)
return initial_data
def get_type(self):
return self.object.type
def get_context_data(self, **kwargs): def get_context_data(self, **kwargs):
context = { context = {
'app': _('Applications'), 'app': _('Applications'),
'action': _('Update RemoteApp'), 'action': _('Update RemoteApp'),
'type': 'update' 'api_action': 'update'
} }
kwargs.update(context) kwargs.update(context)
return super().get_context_data(**kwargs) return super().get_context_data(**kwargs)
def get_success_message(self, cleaned_data):
return update_success_msg % ({'name': cleaned_data['name']})
class RemoteAppDetailView(PermissionsMixin, DetailView): class RemoteAppDetailView(PermissionsMixin, DetailView):
template_name = 'applications/remote_app_detail.html' template_name = 'applications/remote_app_detail.html'
......
...@@ -51,12 +51,13 @@ class CustomMetaDictField(serializers.DictField): ...@@ -51,12 +51,13 @@ class CustomMetaDictField(serializers.DictField):
CommandStorage meta field CommandStorage meta field
ReplayStorage meta field ReplayStorage meta field
""" """
type_map_fields = {} type_fields_map = {}
default_type = None default_type = None
need_convert_key = False convert_key_remove_type_prefix = False
convert_key_to_upper = False
def filter_attribute(self, attribute, instance): def filter_attribute(self, attribute, instance):
fields = self.type_map_fields.get(instance.type, []) fields = self.type_fields_map.get(instance.type, [])
for field in fields: for field in fields:
if field.get('write_only', False): if field.get('write_only', False):
attribute.pop(field['name'], None) attribute.pop(field['name'], None)
...@@ -70,29 +71,35 @@ class CustomMetaDictField(serializers.DictField): ...@@ -70,29 +71,35 @@ class CustomMetaDictField(serializers.DictField):
attribute = self.filter_attribute(attribute, instance) attribute = self.filter_attribute(attribute, instance)
return attribute return attribute
def convert_value_key(self, dictionary, value): def convert_value_key_remove_type_prefix(self, dictionary, value):
if not self.need_convert_key: if not self.convert_key_remove_type_prefix:
# remote app
return value return value
tp = dictionary.get('type') tp = dictionary.get('type')
_value = {}
for k, v in value.items():
prefix = '{}_'.format(tp) prefix = '{}_'.format(tp)
_k = k convert_value = {}
for k, v in value.items():
if k.lower().startswith(prefix): if k.lower().startswith(prefix):
_k = k.lower().split(prefix, 1)[1] k = k.lower().split(prefix, 1)[1]
_k = _k.upper() convert_value[k] = v
_value[_k] = value[k] return convert_value
return _value
def convert_value_key_to_upper(self, value):
if not self.convert_key_to_upper:
return value
convert_value = {k.upper(): v for k, v in value.items()}
return convert_value
def convert_value_key(self, dictionary, value):
value = self.convert_value_key_remove_type_prefix(dictionary, value)
value = self.convert_value_key_to_upper(value)
return value
def filter_value_key(self, dictionary, value): def filter_value_key(self, dictionary, value):
tp = dictionary.get('type', self.default_type) tp = dictionary.get('type')
fields = self.type_map_fields.get(tp, []) fields = self.type_fields_map.get(tp, [])
fields_names = [field['name'] for field in fields] fields_names = [field['name'] for field in fields]
no_need_keys = [k for k in value.keys() if k not in fields_names] filter_value = {k: v for k, v in value.items() if k in fields_names}
for k in no_need_keys: return filter_value
value.pop(k)
return value
def get_value(self, dictionary): def get_value(self, dictionary):
""" """
......
...@@ -49,7 +49,7 @@ REPLAY_STORAGE_TYPE_AZURE_FIELDS = [ ...@@ -49,7 +49,7 @@ REPLAY_STORAGE_TYPE_AZURE_FIELDS = [
{'name': 'ENDPOINT_SUFFIX'} {'name': 'ENDPOINT_SUFFIX'}
] ]
REPLAY_STORAGE_TYPE_MAP_FIELDS = { REPLAY_STORAGE_TYPE_FIELDS_MAP = {
REPLAY_STORAGE_TYPE_NULL: REPLAY_STORAGE_TYPE_EMPTY_FIELDS, REPLAY_STORAGE_TYPE_NULL: REPLAY_STORAGE_TYPE_EMPTY_FIELDS,
REPLAY_STORAGE_TYPE_SERVER: REPLAY_STORAGE_TYPE_EMPTY_FIELDS, REPLAY_STORAGE_TYPE_SERVER: REPLAY_STORAGE_TYPE_EMPTY_FIELDS,
REPLAY_STORAGE_TYPE_S3: REPLAY_STORAGE_TYPE_S3_FIELDS, REPLAY_STORAGE_TYPE_S3: REPLAY_STORAGE_TYPE_S3_FIELDS,
...@@ -89,7 +89,7 @@ COMMAND_STORAGE_TYPE_ES_FIELDS = [ ...@@ -89,7 +89,7 @@ COMMAND_STORAGE_TYPE_ES_FIELDS = [
{'name': 'DOC_TYPE'} {'name': 'DOC_TYPE'}
] ]
COMMAND_STORAGE_TYPE_MAP_FIELDS = { COMMAND_STORAGE_TYPE_FIELDS_MAP = {
COMMAND_STORAGE_TYPE_NULL: COMMAND_STORAGE_TYPE_EMPTY_FIELDS, COMMAND_STORAGE_TYPE_NULL: COMMAND_STORAGE_TYPE_EMPTY_FIELDS,
COMMAND_STORAGE_TYPE_SERVER: COMMAND_STORAGE_TYPE_EMPTY_FIELDS, COMMAND_STORAGE_TYPE_SERVER: COMMAND_STORAGE_TYPE_EMPTY_FIELDS,
COMMAND_STORAGE_TYPE_ES: COMMAND_STORAGE_TYPE_ES_FIELDS, COMMAND_STORAGE_TYPE_ES: COMMAND_STORAGE_TYPE_ES_FIELDS,
......
...@@ -9,13 +9,14 @@ from .. import const ...@@ -9,13 +9,14 @@ from .. import const
class ReplayStorageMetaDictField(CustomMetaDictField): class ReplayStorageMetaDictField(CustomMetaDictField):
type_map_fields = const.REPLAY_STORAGE_TYPE_MAP_FIELDS type_fields_map = const.REPLAY_STORAGE_TYPE_FIELDS_MAP
default_type = const.REPLAY_STORAGE_TYPE_SERVER default_type = const.REPLAY_STORAGE_TYPE_SERVER
need_convert_key = True convert_key_remove_type_prefix = True
convert_key_to_upper = True
class BaseStorageSerializerMixin: class BaseStorageSerializerMixin:
type_map_fields = None type_fields_map = None
def process_meta(self, instance, validated_data): def process_meta(self, instance, validated_data):
new_meta = copy.deepcopy(validated_data.get('meta', {})) new_meta = copy.deepcopy(validated_data.get('meta', {}))
...@@ -25,7 +26,7 @@ class BaseStorageSerializerMixin: ...@@ -25,7 +26,7 @@ class BaseStorageSerializerMixin:
return new_meta return new_meta
old_meta = instance.meta old_meta = instance.meta
fields = self.type_map_fields.get(instance.type, []) fields = self.type_fields_map.get(instance.type, [])
for field in fields: for field in fields:
if not field.get('write_only', False): if not field.get('write_only', False):
continue continue
...@@ -48,7 +49,7 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin, ...@@ -48,7 +49,7 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
meta = ReplayStorageMetaDictField() meta = ReplayStorageMetaDictField()
type_map_fields = const.REPLAY_STORAGE_TYPE_MAP_FIELDS type_fields_map = const.REPLAY_STORAGE_TYPE_FIELDS_MAP
class Meta: class Meta:
model = ReplayStorage model = ReplayStorage
...@@ -56,9 +57,10 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin, ...@@ -56,9 +57,10 @@ class ReplayStorageSerializer(BaseStorageSerializerMixin,
class CommandStorageMetaDictField(CustomMetaDictField): class CommandStorageMetaDictField(CustomMetaDictField):
type_map_fields = const.COMMAND_STORAGE_TYPE_MAP_FIELDS type_fields_map = const.COMMAND_STORAGE_TYPE_FIELDS_MAP
default_type = const.COMMAND_STORAGE_TYPE_SERVER default_type = const.COMMAND_STORAGE_TYPE_SERVER
need_convert_key = True convert_key_remove_type_prefix = True
convert_key_to_upper = True
class CommandStorageSerializer(BaseStorageSerializerMixin, class CommandStorageSerializer(BaseStorageSerializerMixin,
...@@ -66,7 +68,7 @@ class CommandStorageSerializer(BaseStorageSerializerMixin, ...@@ -66,7 +68,7 @@ class CommandStorageSerializer(BaseStorageSerializerMixin,
meta = CommandStorageMetaDictField() meta = CommandStorageMetaDictField()
type_map_fields = const.COMMAND_STORAGE_TYPE_MAP_FIELDS type_fields_map = const.COMMAND_STORAGE_TYPE_FIELDS_MAP
class Meta: class Meta:
model = CommandStorage model = CommandStorage
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment