valar 1.0.21__py3-none-any.whl → 1.0.23__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of valar might be problematic. Click here for more details.

Files changed (63) hide show
  1. valar/__init__.py +0 -26
  2. valar/channels/__init__.py +1 -107
  3. valar/channels/consumer.py +48 -0
  4. valar/channels/executer.py +13 -0
  5. valar/channels/mapping.py +21 -0
  6. valar/channels/sender.py +60 -0
  7. valar/channels/views.py +6 -11
  8. valar/core/__init__.py +0 -0
  9. valar/core/counter.py +9 -0
  10. valar/core/dao/__init__.py +0 -0
  11. valar/core/dao/_mon_array2tree.py +18 -0
  12. valar/core/dao/dao_base.py +50 -0
  13. valar/core/dao/dao_mon.py +76 -0
  14. valar/core/dao/dao_orm.py +96 -0
  15. valar/core/dao/engine.py +12 -0
  16. valar/core/dao/engine_minio.py +90 -0
  17. valar/core/dao/engine_mon.py +34 -0
  18. valar/core/dao/engine_orm.py +25 -0
  19. valar/core/dao/model_mon.py +24 -0
  20. valar/core/dao/model_orm.py +192 -0
  21. valar/core/dao/query_mon.py +12 -0
  22. valar/core/dao/query_orm.py +43 -0
  23. valar/core/dao/utils_orm.py +85 -0
  24. valar/core/dao_abstract.py +63 -0
  25. valar/core/meta/__init__.py +0 -0
  26. valar/core/meta/defaults/__init__.py +0 -0
  27. valar/core/meta/defaults/field_keys_default.py +17 -0
  28. valar/core/meta/defaults/field_values_default.py +85 -0
  29. valar/core/meta/defaults/frame_defaults.py +136 -0
  30. valar/core/meta/defaults/view_defaults.py +7 -0
  31. valar/core/meta/field_orm.py +144 -0
  32. valar/core/meta/init_meta_frame.py +30 -0
  33. valar/core/meta/meta_orm.py +69 -0
  34. valar/core/middleware.py +20 -0
  35. valar/core/response.py +7 -0
  36. valar/core/singleton_meta.py +6 -0
  37. valar/core/valar_models.py +82 -0
  38. valar/data/migrations/0001_initial.py +141 -0
  39. valar/data/models.py +2 -121
  40. valar/data/urls.py +15 -21
  41. valar/data/views/__init__.py +0 -0
  42. valar/data/views/handler.py +41 -0
  43. valar/data/views/rest.py +86 -0
  44. {valar-1.0.21.dist-info → valar-1.0.23.dist-info}/METADATA +1 -1
  45. valar-1.0.23.dist-info/RECORD +50 -0
  46. {valar-1.0.21.dist-info → valar-1.0.23.dist-info}/WHEEL +1 -1
  47. valar/channels/utils.py +0 -43
  48. valar/data/file/__init__.py +0 -91
  49. valar/data/handlers.py +0 -28
  50. valar/data/mon/__init__.py +0 -123
  51. valar/data/mon/query_translator.py +0 -91
  52. valar/data/orm/__init__.py +0 -135
  53. valar/data/orm/detacher.py +0 -61
  54. valar/data/orm/meta.py +0 -99
  55. valar/data/orm/meta_frame.py +0 -100
  56. valar/data/orm/meta_loader.py +0 -200
  57. valar/data/orm/values.py +0 -102
  58. valar/data/query.py +0 -48
  59. valar/data/utils.py +0 -70
  60. valar/data/views.py +0 -173
  61. valar-1.0.21.dist-info/RECORD +0 -26
  62. {valar-1.0.21.dist-info → valar-1.0.23.dist-info}/licenses/LICENSE +0 -0
  63. {valar-1.0.21.dist-info → valar-1.0.23.dist-info}/top_level.txt +0 -0
@@ -1,91 +0,0 @@
1
- class MongoQueryTranslator:
2
- # 将Django ORM查询操作符映射到MongoDB操作符的字典
3
- MONGO_OPERATORS = {
4
- 'exact': lambda v, e: {'$ne': v} if e else v,
5
- 'iexact': lambda v, e: {'$not': {'$regex': f'^{v}$', '$options': 'i'}} if e else {'$regex': f'^{v}$', '$options': 'i'},
6
- 'contains': lambda v, e: {'$not': {'$regex': f'{v}'}} if e else {'$regex': f'{v}'},
7
- 'icontains': lambda v, e: {'$not': {'$regex': f'{v}', '$options': 'i'}} if e else {'$regex': f'{v}', '$options': 'i'},
8
- 'startswith': lambda v, e: {'$not': {'$regex': f'^{v}'}} if e else {'$regex': f'^{v}'},
9
- 'istartswith': lambda v, e: {'$not': {'$regex': f'^{v}', '$options': 'i'}} if e else {'$regex': f'^{v}', '$options': 'i'},
10
- 'endswith': lambda v, e: {'$not': {'$regex': f'{v}$'}} if e else {'$regex': f'{v}$'},
11
- 'iendswith': lambda v, e: {'$not': {'$regex': f'{v}$', '$options': 'i'}} if e else {'$regex': f'{v}$', '$options': 'i'},
12
- 'gt': lambda v, e: {'$not': {'$gt': v}} if e else {'$gt': v},
13
- 'gte': lambda v, e: {'$not': {'$gte': v}} if e else {'$gte': v},
14
- 'lt': lambda v, e: {'$not': {'$lt': v}} if e else {'$lt': v},
15
- 'lte': lambda v, e: {'$not': {'$lte': v}} if e else {'$lte': v},
16
- 'in': lambda v, e: {'$nin': v} if e else {'$in': v},
17
- 'exists': lambda v, e: {'$eq': None} if (e and bool(v)) or (not e and not bool(v)) else {'$ne': None},
18
- 'isnull': lambda v, e: {'$ne': None} if e else {'$eq': None},
19
- }
20
-
21
- @classmethod
22
- def process_field_query(cls, key, value, is_exclude=False):
23
- """处理单个字段查询"""
24
- if '__' in key:
25
- field, op = key.split('__', 1)
26
- if op in cls.MONGO_OPERATORS:
27
- return field, cls.MONGO_OPERATORS[op](value, is_exclude)
28
- return key, {'$ne': value} if is_exclude else value
29
-
30
- @classmethod
31
- def process_condition(cls, condition_dict, is_exclude=False):
32
- """处理条件字典,返回MongoDB查询条件"""
33
- return {field: query for field, query in
34
- [cls.process_field_query(k, v, is_exclude) for k, v in condition_dict.items()]}
35
-
36
- @classmethod
37
- def process_finder(cls, finder):
38
- """处理finder字段,转换为MongoDB查询条件"""
39
- if not finder:
40
- return {}
41
- mongo_query = {}
42
- if 'term' in finder and finder['term'] and isinstance(finder['term'], str):
43
- term = finder['term']
44
- fields = finder.get('fields', [])
45
- if fields:
46
- mongo_query['$or'] = [{field: {'$regex': term, '$options': 'i'}} for field in fields]
47
- else:
48
- mongo_query['$text'] = {'$search': term}
49
- if 'range' in finder:
50
- for field, ranges in finder['range'].items():
51
- field_query = {f'${op}': val for op, val in ranges.items() if op in ['gt', 'gte', 'lt', 'lte']}
52
- if field_query:
53
- mongo_query[field] = field_query
54
- for query_type, operator in [('match', None), ('exists', '$ne')]:
55
- if query_type in finder:
56
- for field, value in finder[query_type].items():
57
- if operator == '$ne':
58
- # 处理exists查询,检查字段是否为空
59
- mongo_query[field] = {'$ne': None} if bool(value) else {'$eq': None}
60
- else:
61
- mongo_query[field] = value
62
- return mongo_query
63
-
64
- @classmethod
65
- def translate_query(cls, query_obj):
66
- """
67
- 将Query对象转换为MongoDB查询
68
- Args:
69
- query_obj: Query对象,包含condition, search和finder
70
- Returns:
71
- 转换后的MongoDB查询条件
72
- """
73
- query = {}
74
- query.update(cls.process_condition(query_obj.condition.includes))
75
- query.update(cls.process_condition(query_obj.condition.excludes, True))
76
- # 处理搜索条件
77
- if query_obj.search:
78
- or_conditions = []
79
- for sea in query_obj.search:
80
- search_query = {}
81
- search_query.update(cls.process_condition(sea.includes))
82
- search_query.update(cls.process_condition(sea.excludes, True))
83
- if search_query:
84
- or_conditions.append(search_query)
85
- if or_conditions:
86
- query["$or"] = or_conditions
87
- # 处理和合并finder条件
88
- finder_query = cls.process_finder(query_obj.finder)
89
- if finder_query and query:
90
- return {"$and": [query, finder_query]}
91
- return finder_query or query
@@ -1,135 +0,0 @@
1
- import datetime
2
- from django.apps import apps
3
- from django.core.paginator import Paginator
4
- from django.db.models import Manager, QuerySet, FileField
5
-
6
- from .meta_frame import load_meta_frame
7
- from ..file import minio_remove_path
8
- from ..orm.detacher import detach_props, save_detached
9
- from ..orm.meta_loader import load_meta, load_view, load_meta_field
10
- from ..models import VModel, VTree
11
- from ..query import Query
12
-
13
-
14
- load_meta_frame()
15
-
16
- def load_model(entity=None):
17
- mapping = {}
18
- for mod in apps.get_models():
19
- if issubclass(mod, VModel):
20
- path, name = mod.__module__, mod.__name__
21
- __old = 'src.valar.' if path.startswith('src') else 'valar.'
22
- app = path.replace('.models', '').replace(__old,'')
23
- key = '%s.%s' % (app, name)
24
- verbose_name = mod._meta.verbose_name
25
- mapping[key] = [mod, verbose_name]
26
- return mapping.get(entity) if entity else mapping
27
-
28
-
29
-
30
-
31
- class OrmDao:
32
- def __init__(self, entity):
33
- self.entity = entity
34
- param = load_model(entity)
35
- if param is None:
36
- raise Exception('no entity named %s' % entity)
37
- self.model = param[0]
38
- self.isTree = issubclass(self.model, VTree)
39
- self.name: str = param[1]
40
- self.manager: Manager = self.model.objects
41
- self.meta_fields = {}
42
- self.model_fields = {}
43
- for field in self.model._meta.get_fields():
44
- _field = load_meta_field(field, self.isTree)
45
- prop = _field['prop']
46
- self.model_fields[prop] = field
47
- self.meta_fields[prop] = _field
48
-
49
-
50
- def tree(self, query: Query, root_id = 0):
51
- all_set, _ = self.find_many(Query())
52
- includes, excludes = query.orm_conditions()
53
- if not len(includes) + len(excludes) + root_id:
54
- return all_set
55
- values = all_set.values('id','pid')
56
- mapping = {item['id']: item['pid'] for item in values}
57
- results, _ = self.find_many(query)
58
- id_set = {root_id}
59
- for item in results:
60
- _id = item.id
61
- route = []
62
- while _id is not None:
63
- route.append(_id)
64
- _id = mapping.get(_id)
65
- if root_id in route:
66
- id_set.update(route)
67
- return all_set.filter(id__in=id_set).order_by('-sort')
68
-
69
- def __check_remove_file__(self, query_set, template:dict = None):
70
- props = [key for key in self.model_fields if type(self.model_fields[key]) == FileField]
71
- keys = [ key for key in props if template.get(key, 1) is None] if template else props
72
- if len(keys):
73
- values = query_set.values(*props)
74
- for row in values:
75
- for path in row.values():
76
- if path:
77
- print(path)
78
- minio_remove_path(path)
79
-
80
-
81
-
82
- def save_one(self, item):
83
- _item = detach_props(item, self.meta_fields.values())
84
- _id = item.get('id',0)
85
- query_set = self.manager.filter(id=_id)
86
- if len(query_set):
87
- del item['id']
88
- item['modify_time'] = datetime.datetime.now()
89
- self.__check_remove_file__(query_set,item)
90
- query_set.update(**item)
91
- bean = query_set.first()
92
- else:
93
- bean = self.manager.create(**item)
94
- bean.sort = bean.id
95
- bean.save()
96
- save_detached(bean, _item, self.model_fields)
97
- return bean
98
-
99
- def update_many(self, query: Query, template):
100
- query_set, total = self.find_many(query)
101
- query_set.update(**template)
102
-
103
- def delete_one(self, _id):
104
- query_set = self.manager.filter(id=_id)
105
- self.__check_remove_file__(query_set)
106
- query_set.delete()
107
-
108
- def delete_many(self, query: Query):
109
- query_set, total = self.find_many(query)
110
- self.__check_remove_file__(query_set)
111
- query_set.delete()
112
-
113
- def find_one(self, _id):
114
- return self.manager.filter(id=_id).first()
115
-
116
- def find_many(self, query: Query, size=0, page=1):
117
- includes, excludes = query.orm_conditions()
118
- query_set = self.manager.filter(includes).exclude(excludes).order_by(*query.orm_orders())
119
- total = query_set.count()
120
- if size:
121
- paginator = Paginator(query_set, size)
122
- query_set = paginator.page(page).object_list
123
- return query_set, total
124
-
125
-
126
- def meta(self, code:str = 'default'):
127
- omit = [ 'id', 'saved', 'sort', 'create_time', 'modify_time']
128
- fields = [ self.meta_fields[prop] for prop in self.meta_fields if prop not in omit]
129
- view = load_view(self.entity, code, self.name, fields)
130
- _view = load_meta(view)
131
- _view['isTree'] = self.isTree
132
- return _view
133
-
134
-
135
-
@@ -1,61 +0,0 @@
1
- from django.db.models import (ManyToOneRel, ForeignKey, ManyToManyRel, ManyToManyField, OneToOneField, CharField,
2
- OneToOneRel, IntegerField, BooleanField, FloatField, FileField, JSONField, DateField,
3
- DateTimeField, TimeField, QuerySet)
4
-
5
- from ..models import VModel
6
-
7
-
8
- def detach_props(item, fields):
9
- keys = [field['prop'] for field in fields if
10
- field['domain'] in ['ManyToOneRel', 'ManyToManyField', 'ManyToManyRel', 'OneToOneRel', 'OneToOneField']]
11
- _item = {}
12
- for key in keys:
13
- value = item.get(key)
14
- if value is not None:
15
- _item[key] = value
16
- del item[key]
17
- return _item
18
-
19
- def save_detached(bean, _item, model_fields ):
20
- for prop in _item:
21
- value = _item[prop]
22
- field = model_fields.get(prop)
23
- clazz = type(field)
24
- if clazz == ManyToManyField:
25
- m2m = getattr(bean, prop)
26
- m2m.clear()
27
- m2m.add(*value)
28
- elif clazz == ManyToOneRel:
29
- getattr(bean, field.get_accessor_name()).clear()
30
- remote_model: VModel = field.related_model
31
- new_set: QuerySet = remote_model.objects.filter(id__in=value)
32
- remote_field: ForeignKey = field.remote_field
33
- k = remote_field.get_attname()
34
- new_set.update(**{k: bean.id})
35
- elif clazz == ManyToManyRel:
36
- getattr(bean, field.get_accessor_name()).clear()
37
- remote_model: VModel = field.related_model
38
- remote_items: QuerySet = remote_model.objects.filter(id__in=value)
39
- remote_field: ManyToManyField = field.remote_field
40
- remote_field_prop = remote_field.get_attname()
41
- for _bean in remote_items:
42
- bean_set = getattr(_bean, remote_field_prop)
43
- bean_set.add(bean)
44
- elif clazz == OneToOneRel:
45
- remote_model: VModel = field.related_model
46
- remote_field: OneToOneField = field.remote_field
47
- remote_field_prop = remote_field.get_attname()
48
- _bean = remote_model.objects.get(id=value)
49
- __bean = remote_model.objects.filter(**{remote_field_prop: bean.id}).first()
50
- if __bean:
51
- setattr(__bean, remote_field_prop, None)
52
- __bean.save()
53
- setattr(_bean, remote_field_prop, bean.id)
54
- _bean.save()
55
- elif clazz == OneToOneField:
56
- __bean = field.model.objects.filter(**{prop: value}).first()
57
- if __bean:
58
- setattr(__bean, prop, None)
59
- __bean.save()
60
- setattr(bean, prop, value)
61
- bean.save()
valar/data/orm/meta.py DELETED
@@ -1,99 +0,0 @@
1
- mf_common = ['prop','name']
2
-
3
- meta_props = {
4
- 'data.Meta': {
5
- 'default': ('pick', ['entity','name']),
6
- },
7
- 'data.MetaView': {
8
- 'list': ('pick', ['meta_id','code','view_name']),
9
- },
10
- 'data.MetaField': {
11
- 'add': ('pick',['prop','domain','name']),
12
- 'tool': ('pick',[*mf_common,'domain','tool','refer','format']),
13
- 'rest': ('pick',[*mf_common,'not_null','allow_edit','allow_sort','allow_search','allow_download','allow_upload','allow_update']),
14
- 'table': ('pick',[*mf_common,'unit','column_width','fixed','align','edit_on_table','hide_on_table','header_color','cell_color']),
15
- 'form': ('pick',[*mf_common,'hide_on_form','hide_on_form_insert','hide_on_form_edit','hide_on_form_branch','hide_on_form_leaf','span']),
16
- }
17
- }
18
-
19
-
20
- meta_defaults = {
21
- 'data.MetaFieldDomain':{
22
- "default_id":{
23
- "tool":"tree"
24
- },
25
- "search_id":{
26
- "tool":"tree"
27
- },
28
- "tools":{
29
- "tool":"tree",
30
- "refer": {
31
- "display":"code"
32
- }
33
- },
34
- "align":{
35
- "tool":"set",
36
- "format":{
37
- "set": {
38
- 'left':'左对齐',
39
- 'right':'右对齐',
40
- 'center':'剧中对齐',
41
- }
42
- }
43
- }
44
- },
45
- 'data.MetaField':{
46
- "column_width":{
47
- 'unit':'px'
48
- },
49
- "fixed":{
50
- "tool":"set",
51
- "format":{
52
- "set": {
53
- 'left':'左侧固定',
54
- 'right':'右侧固定',
55
- }
56
- }
57
- },
58
- "align":{
59
- "tool":"set",
60
- "format":{
61
- "set": {
62
- 'left':'左对齐',
63
- 'right':'右对齐',
64
- 'center':'剧中对齐',
65
- }
66
- }
67
- },
68
- "prop":{
69
- 'allow_edit': False,
70
- 'column_width': 120
71
- },
72
- "domain":{
73
- 'allow_edit': False,
74
- 'column_width': 120,
75
- },
76
- "tool":{
77
- 'column_width': 100,
78
- 'tool': 'tree',
79
- 'refer': {
80
- 'entity':'data.MetaFieldTool',
81
- 'includes': {'metafielddomain__name':'$domain'},
82
- 'value': 'code'
83
- }
84
-
85
- },
86
- "span":{
87
- 'column_width': 100,
88
- "format": { "min": 0, "max": 24, "step": 1, "precision": 0, "step_strictly": True }
89
- },
90
- "refer":{
91
- 'allow_edit': False,
92
- 'column_width': 80
93
- },
94
- "format":{
95
- 'allow_edit': False,
96
- 'column_width': 80
97
- },
98
- }
99
- }
@@ -1,100 +0,0 @@
1
-
2
- from django.db import OperationalError
3
-
4
- from ...data.models import MetaFieldDomain, MetaFieldTool
5
-
6
-
7
- def load_meta_frame():
8
- try:
9
- MetaFieldTool.objects.all().delete()
10
- MetaFieldDomain.objects.all().delete()
11
- for row in meta_field_tool:
12
- row['saved'] = True
13
- MetaFieldTool.objects.create(**row)
14
- for row in meta_field_domain:
15
- row['saved'] = True
16
- tools = row.get('tools', '').split(';')
17
- del row['tools']
18
- item = MetaFieldDomain.objects.create(**row)
19
- for tk in tools:
20
- item.tools.add(tk)
21
- except OperationalError as e:
22
- print('initialization')
23
-
24
-
25
- def convert_meta_fields(fields, entity):
26
- values = MetaFieldDomain.objects.all().values('name', 'default__code', 'align')
27
- mapping = {vs['name']: {
28
- "tool": vs['default__code'],
29
- "align": vs['align']
30
- } for vs in values}
31
- array = []
32
- for field in fields:
33
- node = mapping[field.domain]
34
- _field = field.json
35
- if field.tool == 'default':
36
- _field['tool'] = node['tool']
37
- _field['align'] = node['align']
38
- _field['entity'] = entity
39
- array.append(_field)
40
- return array
41
-
42
-
43
-
44
- meta_field_tool = [
45
- {'id': 2, 'sort': 32, 'pid': 7, 'isLeaf': True, 'name': '输入框', 'code': 'text'},
46
- {'id': 3, 'sort': 17, 'pid': 0, 'isLeaf': False, 'name': 'SPEC', 'code': '特殊工具集'},
47
- {'id': 5, 'sort': 22, 'pid': 0, 'isLeaf': False, 'name': 'DATE', 'code': '日期时间工具集'},
48
- {'id': 6, 'sort': 21, 'pid': 8, 'isLeaf': True, 'name': '数字输入', 'code': 'number'},
49
- {'id': 7, 'sort': 36, 'pid': 0, 'isLeaf': False, 'name': 'TEXT', 'code': '文本工具集'},
50
- {'id': 8, 'sort': 26, 'pid': 0, 'isLeaf': False, 'name': 'NUMB', 'code': '数字工具集'},
51
- {'id': 9, 'sort': 10, 'pid': 0, 'isLeaf': False, 'name': 'FILE', 'code': '文件工具集'},
52
- {'id': 10, 'sort': 27, 'pid': 0, 'isLeaf': False, 'name': 'BOOL', 'code': '逻辑工具集'},
53
- {'id': 11, 'sort': 31, 'pid': 0, 'isLeaf': False, 'name': 'LIST', 'code': '列表工具集'},
54
- {'id': 12, 'sort': 8, 'pid': 3, 'isLeaf': True, 'name': '对象', 'code': 'object'},
55
- {'id': 13, 'sort': 5, 'pid': 9, 'isLeaf': True, 'name': '图片上传', 'code': 'image'},
56
- {'id': 14, 'sort': 2, 'pid': 9, 'isLeaf': True, 'name': '文件上传', 'code': 'file'},
57
- {'id': 15, 'sort': 13, 'pid': 9, 'isLeaf': True, 'name': '富文本', 'code': 'rich'},
58
- {'id': 17, 'sort': 11, 'pid': 10, 'isLeaf': True, 'name': '开关', 'code': 'switch'},
59
- {'id': 18, 'sort': 7, 'pid': 3, 'isLeaf': True, 'name': '元数据', 'code': 'meta'},
60
- {'id': 19, 'sort': 9, 'pid': 7, 'isLeaf': True, 'name': '颜色选择', 'code': 'color'},
61
- {'id': 20, 'sort': 14, 'pid': 11, 'isLeaf': True, 'name': '穿梭框', 'code': 'transfer'},
62
- {'id': 21, 'sort': 16, 'pid': 7, 'isLeaf': True, 'name': '自动填充', 'code': 'auto'},
63
- {'id': 22, 'sort': 35, 'pid': 5, 'isLeaf': True, 'name': '日期选择', 'code': 'date'},
64
- {'id': 23, 'sort': 12, 'pid': 10, 'isLeaf': True, 'name': '逻辑选择', 'code': 'boolean'},
65
- {'id': 24, 'sort': 24, 'pid': 11, 'isLeaf': True, 'name': '列表选择', 'code': 'select'},
66
- {'id': 25, 'sort': 15, 'pid': 11, 'isLeaf': True, 'name': '树形选择', 'code': 'tree'},
67
- {'id': 26, 'sort': 23, 'pid': 11, 'isLeaf': True, 'name': '及联选择', 'code': 'cascade'},
68
- {'id': 27, 'sort': 39, 'pid': 0, 'isLeaf': True, 'name': '默认', 'code': 'default'},
69
- {'id': 28, 'sort': 25, 'pid': 7, 'isLeaf': True, 'name': '图标', 'code': 'icon'},
70
- {'id': 31, 'sort': 6, 'pid': 0, 'isLeaf': True, 'name': '无', 'code': 'none'},
71
- {'id': 32, 'sort': 30, 'pid': 7, 'isLeaf': True, 'name': '文本框', 'code': 'textarea'},
72
- {'id': 33, 'sort': 18, 'pid': 36, 'isLeaf': True, 'name': '时间区间', 'code': 'timerange'},
73
- {'id': 35, 'sort': 33, 'pid': 5, 'isLeaf': True, 'name': '时间选择', 'code': 'time'},
74
- {'id': 36, 'sort': 20, 'pid': 0, 'isLeaf': False, 'name': 'RANGE', 'code': '区间工具集'},
75
- {'id': 37, 'sort': 38, 'pid': 36, 'isLeaf': True, 'name': '日期区间', 'code': 'daterange'},
76
- {'id': 39, 'sort': 3, 'pid': 36, 'isLeaf': True, 'name': '多日期', 'code': 'dates'},
77
- {'id': 54, 'sort': 54, 'pid': 7, 'isLeaf': True, 'name': '集合', 'code': 'set'}
78
- ]
79
-
80
- meta_field_domain = [
81
- {'id': 12, 'sort': 22, 'name': 'CharField', 'default_id': 2, 'align': 'left', 'tools': '2;6;18;19;21;22;24;25;26;27;28;31;32;33;37;39;54'},
82
- {'id': 11, 'sort': 21, 'name': 'TextField', 'default_id': 32, 'align': 'left', 'tools': '2;27;31;32'},
83
- {'id': 13, 'sort': 20, 'name': 'BooleanField', 'default_id': 17, 'align': 'center', 'tools': '17;23;27;31'},
84
- {'id': 9, 'sort': 18, 'name': 'IntegerField', 'default_id': 6, 'align': 'right', 'tools': '6;27;31'},
85
- {'id': 8, 'sort': 16, 'name': 'FloatField', 'default_id': 6, 'align': 'right', 'tools': '6;27;31'},
86
- {'id': 4, 'sort': 15, 'name': 'ForeignKey', 'default_id': 24, 'align': 'left', 'tools': '24;25;26;27;31'},
87
- {'id': 2, 'sort': 13, 'name': 'ManyToOneRel', 'default_id': 24, 'align': 'center', 'tools': '20;24;25;26;27;31'},
88
- {'id': 1, 'sort': 12, 'name': 'ManyToManyField', 'default_id': 24, 'align': 'center', 'tools': '20;24;25;26;27;31'},
89
- {'id': 22, 'sort': 11, 'name': 'ManyToManyRel', 'default_id': 24, 'align': 'center', 'tools': '20;24;25;26;27;31'},
90
- {'id': 5, 'sort': 10, 'name': 'OneToOneRel', 'default_id': 31, 'align': 'left', 'tools': '27;31'},
91
- {'id': 21, 'sort': 9, 'name': 'OneToOneField', 'default_id': 31, 'align': 'left', 'tools': '27;31'},
92
- {'id': 6, 'sort': 8, 'name': 'DateField', 'default_id': 22, 'align': 'center', 'tools': '22;27;31'},
93
- {'id': 20, 'sort': 7, 'name': 'TimeField', 'default_id': 35, 'align': 'center', 'tools': '27;31;35'},
94
- {'id': 7, 'sort': 6, 'name': 'DateTimeField', 'default_id': 22, 'align': 'center', 'tools': '22;27;31'},
95
- {'id': 3, 'sort': 5, 'name': 'JSONField', 'default_id': 12, 'align': 'center', 'tools': '12;27;31'},
96
- {'id': 15, 'sort': 4, 'name': 'FileField', 'default_id': 14, 'align': 'center', 'tools': '13;14;15;27;31'},
97
- {'id': 16, 'sort': 3, 'name': 'BigAutoField', 'default_id': 31, 'align': 'right', 'tools': '27;31'},
98
- {'id': 18, 'sort': 2, 'name': 'UUIDField', 'default_id': 31, 'align': 'left', 'tools': '27;31'},
99
- {'id': 10, 'sort': 1, 'name': 'Custom', 'default_id': 31, 'align': 'left', 'tools': '27;31'}
100
- ]