mirror of https://github.com/jumpserver/jumpserver
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
70 lines
2.4 KiB
70 lines
2.4 KiB
from rest_framework import serializers |
|
|
|
example_info = [ |
|
{"name": "name", "label": "姓名", "required": False, "default": "广州老广", "type": "str"}, |
|
{"name": "age", "label": "年龄", "required": False, "default": 18, "type": "int"}, |
|
] |
|
|
|
type_field_map = { |
|
"str": serializers.CharField, |
|
"password": serializers.CharField, |
|
"int": serializers.IntegerField, |
|
"bool": serializers.BooleanField, |
|
"text": serializers.CharField, |
|
"choice": serializers.ChoiceField, |
|
"list": serializers.ListField, |
|
} |
|
|
|
|
|
def set_default_if_need(data, i): |
|
field_name = data.pop('name', 'Attr{}'.format(i + 1)) |
|
data['name'] = field_name |
|
|
|
if not data.get('label'): |
|
data['label'] = field_name |
|
return data |
|
|
|
|
|
def set_default_by_type(tp, data, field_info): |
|
if tp == 'str': |
|
data['max_length'] = 4096 |
|
elif tp == 'password': |
|
data['write_only'] = True |
|
elif tp == 'choice': |
|
choices = field_info.pop('choices', []) |
|
if isinstance(choices, str): |
|
choices = choices.split(',') |
|
choices = [ |
|
(c, c.title()) if not isinstance(c, (tuple, list)) else c |
|
for c in choices |
|
] |
|
data['choices'] = choices |
|
return data |
|
|
|
|
|
def create_serializer_class(serializer_name, fields_info): |
|
serializer_fields = {} |
|
fields_name = ['name', 'label', 'default', 'required', 'type', 'help_text'] |
|
|
|
for i, field_info in enumerate(fields_info): |
|
data = {k: field_info.get(k) for k in fields_name} |
|
field_type = data.pop('type', 'str') |
|
|
|
# 用户定义 default 和 required 可能会冲突, 所以要处理一下 |
|
default = data.get('default', None) |
|
if default is None: |
|
data.pop('default', None) |
|
data['required'] = True |
|
elif default == '': |
|
data['required'] = False |
|
data['allow_blank'] = True |
|
else: |
|
data['required'] = False |
|
data = set_default_by_type(field_type, data, field_info) |
|
data = set_default_if_need(data, i) |
|
if field_type in ['int', 'bool', 'list'] and "allow_blank" in data.keys(): |
|
data.pop('allow_blank') |
|
field_name = data.pop('name') |
|
field_class = type_field_map.get(field_type, serializers.CharField) |
|
serializer_fields[field_name] = field_class(**data) |
|
return type(serializer_name, (serializers.Serializer,), serializer_fields)
|
|
|