valar 1.1.4__py3-none-any.whl → 1.2.1__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 (47) hide show
  1. valar/apps.py +6 -9
  2. valar/channels/consumer.py +10 -12
  3. valar/channels/executer.py +7 -6
  4. valar/channels/sender.py +95 -43
  5. valar/channels/views.py +2 -3
  6. valar/classes/{auto_migration_mixin.py → app_mixins/auto_migration_mixin.py} +2 -2
  7. valar/classes/{auto_urlpatterns_mixin.py → app_mixins/auto_urlpatterns_mixin.py} +3 -3
  8. valar/classes/valar_minio.py +80 -0
  9. valar/classes/valar_response.py +2 -1
  10. valar/dao/__init__.py +45 -0
  11. valar/dao/abstract.py +106 -0
  12. valar/dao/defaults/__init__.py +0 -0
  13. valar/dao/defaults/field_keys_default.py +48 -0
  14. valar/dao/defaults/field_values_default.py +135 -0
  15. valar/dao/defaults/view_defaults.py +26 -0
  16. valar/dao/engine.py +80 -0
  17. valar/dao/frame.py +189 -0
  18. valar/dao/meta.py +128 -0
  19. valar/dao/mon_dao.py +113 -0
  20. valar/dao/mon_field.py +23 -0
  21. valar/dao/orm_dao.py +304 -0
  22. valar/dao/orm_field.py +142 -0
  23. valar/dao/query.py +36 -0
  24. valar/migrations/0001_initial.py +25 -17
  25. valar/models/core.py +16 -10
  26. valar/models/frame.py +4 -7
  27. valar/models/meta.py +19 -16
  28. valar/urls.py +22 -0
  29. valar/views/file.py +49 -0
  30. valar/views/handler.py +33 -0
  31. valar/views/meta.py +150 -0
  32. valar/views/rest.py +90 -0
  33. {valar-1.1.4.dist-info → valar-1.2.1.dist-info}/METADATA +9 -14
  34. valar-1.2.1.dist-info/RECORD +54 -0
  35. {valar-1.1.4.dist-info → valar-1.2.1.dist-info}/top_level.txt +1 -0
  36. vtest/__init__.py +0 -0
  37. vtest/apps.py +17 -0
  38. vtest/handlers.py +15 -0
  39. vtest/migrations/0001_initial.py +155 -0
  40. vtest/migrations/__init__.py +0 -0
  41. vtest/models.py +59 -0
  42. vtest/views.py +8 -0
  43. valar-1.1.4.dist-info/RECORD +0 -28
  44. /valar/{classes → channels}/counter.py +0 -0
  45. /valar/{frame → classes/app_mixins}/__init__.py +0 -0
  46. {valar-1.1.4.dist-info → valar-1.2.1.dist-info}/WHEEL +0 -0
  47. {valar-1.1.4.dist-info → valar-1.2.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,135 @@
1
+ meta_field_value_defaults = {
2
+ 'valar.Meta': {
3
+ "__init__": {
4
+ "db": {
5
+ "tool": "set",
6
+ "format": {
7
+ "set": {
8
+ 'orm': 'SQL',
9
+ 'mon': 'MongoDB',
10
+ 'center': '剧中对齐',
11
+ }
12
+ }
13
+ },
14
+ }
15
+ },
16
+ 'valar.MetaView': {
17
+ "__init__": {
18
+ "meta_id": {
19
+ 'allow_edit': False,
20
+ },
21
+ "code": {
22
+ 'allow_edit': False,
23
+ },
24
+ "name": {
25
+ 'span': 24
26
+ }
27
+ },
28
+ "core": {
29
+ "name": {
30
+ 'span': 16
31
+ },
32
+ "enable": {
33
+ "span": 8
34
+ }
35
+ }
36
+ },
37
+ 'valar.MetaFieldDomain': {
38
+ "__init__": {
39
+ "default_id": {
40
+ "tool": "tree"
41
+ },
42
+ "search_id": {
43
+ "tool": "tree"
44
+ },
45
+ "tools": {
46
+ "tool": "tree",
47
+ "refer": {
48
+ "display": "code"
49
+ }
50
+ },
51
+ "align": {
52
+ "tool": "set",
53
+ "format": {
54
+ "set": {
55
+ 'left': '左对齐',
56
+ 'right': '右对齐',
57
+ 'center': '剧中对齐',
58
+ }
59
+ }
60
+ }
61
+ }
62
+ },
63
+ 'valar.MetaField': {
64
+ "rest": {
65
+ "name": {
66
+ 'hide_on_form': False
67
+ },
68
+ },
69
+ "__init__": {
70
+ "column_width": {
71
+ 'unit': 'px'
72
+ },
73
+ "name": {
74
+ 'span': 24,
75
+ 'hide_on_form': True
76
+ },
77
+ "fixed": {
78
+ "tool": "set",
79
+ "format": {
80
+ "set": {
81
+ 'left': '左侧固定',
82
+ 'right': '右侧固定',
83
+ }
84
+ }
85
+ },
86
+ "align": {
87
+ "tool": "set",
88
+ "format": {
89
+ "set": {
90
+ 'left': '左对齐',
91
+ 'right': '右对齐',
92
+ 'center': '剧中对齐',
93
+ }
94
+ }
95
+ },
96
+ "prop": {
97
+ 'allow_edit': False,
98
+ 'column_width': 120
99
+ },
100
+ "domain": {
101
+ 'allow_edit': False,
102
+ 'column_width': 120,
103
+ },
104
+ "tool": {
105
+ 'column_width': 100,
106
+ 'span': 24,
107
+ 'tool': 'tree',
108
+ 'refer': {
109
+ 'entity': 'valar.MetaFieldTool',
110
+ 'includes': {'metafielddomain__name': '${domain}'},
111
+ 'value': 'code', 'display': 'code', "isTree": True
112
+ }
113
+
114
+ },
115
+ "span": {
116
+ 'column_width': 100,
117
+ "format": {"min": 0, "max": 24, "step": 1, "precision": 0, "step_strictly": True}
118
+ },
119
+ "refer": {
120
+ 'allow_edit': False,
121
+ 'column_width': 80
122
+ },
123
+ "format": {
124
+ 'allow_edit': False,
125
+ 'column_width': 80
126
+ },
127
+ 'header_color': {
128
+ 'tool': 'color',
129
+ },
130
+ 'cell_color': {
131
+ 'tool': 'color',
132
+ }
133
+ }
134
+ }
135
+ }
@@ -0,0 +1,26 @@
1
+ meta_view_default_values = {
2
+ 'valar.Meta': {
3
+ '__init__': {
4
+ 'allow_insert': False,
5
+ 'allow_upload': False,
6
+ 'lock': True
7
+ }
8
+ },
9
+ 'valar.MetaView': {
10
+ '__init__': {
11
+ 'allow_insert': False,
12
+ 'allow_upload': False,
13
+ 'lock': True
14
+ },
15
+ },
16
+ 'valar.MetaField': {
17
+ '__init__': {
18
+ 'allow_insert': False,
19
+ 'allow_upload': False,
20
+ 'lock': True
21
+ },
22
+ 'tool': {
23
+ 'allow_edit_on_form': False,
24
+ }
25
+ }
26
+ }
valar/dao/engine.py ADDED
@@ -0,0 +1,80 @@
1
+ import pymongo
2
+ from django.apps import apps
3
+ from django.conf import settings
4
+ from urllib.parse import urlparse
5
+ from minio import Minio
6
+ from pymongo.synchronous.collection import Collection
7
+
8
+ from ..classes.singleton_meta import SingletonMeta
9
+ from ..classes.valar_minio import ValarMinio
10
+ from ..models.core import VModel, VTree
11
+
12
+
13
+ class ValarEngine(metaclass=SingletonMeta):
14
+
15
+ def __init__(self):
16
+ orm_engine = {}
17
+ for model in apps.get_models():
18
+ meta = getattr(model, '_meta')
19
+ app = meta.app_label
20
+ if app not in ['sessions']:
21
+ entity = f'{app}.{model.__name__}'
22
+ orm_engine[entity] = model
23
+ self.orm_engine = orm_engine
24
+
25
+ # mon
26
+ if hasattr(settings, 'MONGO_URI'):
27
+ self.mongo_client = pymongo.MongoClient(
28
+ settings.MONGO_URI,
29
+ **{
30
+ 'maxPoolSize': 10,
31
+ 'minPoolSize': 0,
32
+ 'maxIdleTimeMS': 10000,
33
+ 'connectTimeoutMS': 10000,
34
+ 'socketTimeoutMS': 10000,
35
+ 'serverSelectionTimeoutMS': 10000,
36
+ }
37
+ )
38
+ self.mongo_engine = self.mongo_client[settings.BASE_APP]
39
+ else:
40
+ self.mongo_client = None
41
+ self.mongo_engine = None
42
+
43
+ # minio
44
+ if hasattr(settings, 'MINIO_URL'):
45
+ parsed = urlparse(settings.MINIO_URL)
46
+ endpoint = f'{parsed.hostname}:{parsed.port}'
47
+ access_key = parsed.username
48
+ secret_key = parsed.password
49
+ self.minio_engine = Minio(
50
+ endpoint=endpoint,
51
+ access_key=access_key,
52
+ secret_key=secret_key,
53
+ secure=False
54
+ )
55
+ else:
56
+ self.minio_engine = None
57
+
58
+ def get_orm_model(self, entity) -> VModel:
59
+ return self.orm_engine[entity]
60
+
61
+ def get_mongo_collection(self, entity) -> Collection:
62
+ return self.mongo_engine[entity]
63
+
64
+ def get_minio_bucket(self, entity):
65
+ return ValarMinio(self.minio_engine, entity) if self.minio_engine else None
66
+
67
+ # def meta_tree(self):
68
+ # mapping = {}
69
+ # names = self.mongo_engine.list_collection_names()
70
+ #
71
+ # for entity, model in self.orm_engine.items():
72
+ # app, value = entity.split('.')
73
+ # is_tree = issubclass(model, VTree)
74
+ # meta = getattr(model, '_meta')
75
+ # name = meta.verbose_name
76
+ #
77
+ # node = mapping.get(app, {'label': app, 'value': app, 'db': 'orm', 'children': []})
78
+ # node['children'].append({"label": name, "value": value, 'isTree': is_tree})
79
+ # mapping[app] = node
80
+ # return list(mapping.values())
valar/dao/frame.py ADDED
@@ -0,0 +1,189 @@
1
+ import copy
2
+
3
+ from ..classes.singleton_meta import SingletonMeta
4
+
5
+
6
+ class MetaFrame(metaclass=SingletonMeta):
7
+ def __init__(self):
8
+ from .orm_dao import OrmDao
9
+ from .meta import ValarMeta
10
+ from ..models.core import VTree
11
+ from .engine import ValarEngine
12
+ tool_dao = OrmDao('valar.MetaFieldTool')
13
+ domain_dao = OrmDao('valar.MetaFieldDomain')
14
+ tool_dao.delete()
15
+ domain_dao.delete()
16
+ mapping = {}
17
+ for item in meta_field_tool:
18
+ item = copy.deepcopy(item)
19
+ _id, code = item['id'], item['code']
20
+ item.update({"saved": True})
21
+ if item['isLeaf']:
22
+ mapping[code] = _id
23
+ tool_dao.save_one(item, True)
24
+ for row in meta_field_domain:
25
+ row = copy.deepcopy(row)
26
+ default_id, tools = row['default_id'], row['tools']
27
+ _row = copy.deepcopy(row)
28
+ _row.update({
29
+ 'default_id': mapping[default_id],
30
+ 'tools': [mapping[tool] for tool in tools],
31
+ "saved": True
32
+ })
33
+ domain_dao.save_one(_row)
34
+
35
+ meta_dao = OrmDao('valar.Meta')
36
+ meta_dao.delete([{"includes": {'db__exact': 'orm', 'entity__startswith': 'valar.'}}])
37
+ engine = ValarEngine()
38
+ for entity, model in engine.orm_engine.items():
39
+ tree = issubclass(model, VTree)
40
+ ValarMeta('orm', entity, 'default')
41
+ cols = engine.mongo_engine.list_collections()
42
+ for col in cols:
43
+ entity = col['name']
44
+ ValarMeta('mon', entity, 'default')
45
+
46
+
47
+ meta_field_tool = [
48
+ {'id': 2, 'sort': 32, 'pid': 7, 'isLeaf': True, 'name': '输入框', 'code': 'text', 'align': 'left'},
49
+ {'id': 3, 'sort': 17, 'pid': 0, 'isLeaf': False, 'name': 'SPEC', 'code': '特殊工具集'},
50
+ {'id': 5, 'sort': 22, 'pid': 0, 'isLeaf': False, 'name': 'DATE', 'code': '日期时间工具集'},
51
+ {'id': 6, 'sort': 21, 'pid': 8, 'isLeaf': True, 'name': '数字输入', 'code': 'number', 'align': 'right'},
52
+ {'id': 7, 'sort': 36, 'pid': 0, 'isLeaf': False, 'name': 'TEXT', 'code': '文本工具集'},
53
+ {'id': 8, 'sort': 26, 'pid': 0, 'isLeaf': False, 'name': 'NUMB', 'code': '数字工具集'},
54
+ {'id': 9, 'sort': 10, 'pid': 0, 'isLeaf': False, 'name': 'FILE', 'code': '文件工具集'},
55
+ {'id': 10, 'sort': 27, 'pid': 0, 'isLeaf': False, 'name': 'BOOL', 'code': '逻辑工具集'},
56
+ {'id': 11, 'sort': 31, 'pid': 0, 'isLeaf': False, 'name': 'LIST', 'code': '列表工具集'},
57
+ {'id': 12, 'sort': 8, 'pid': 3, 'isLeaf': True, 'name': '对象', 'code': 'object', 'align': 'center'},
58
+ {'id': 13, 'sort': 5, 'pid': 9, 'isLeaf': True, 'name': '图片上传', 'code': 'image', 'align': 'center'},
59
+ {'id': 14, 'sort': 2, 'pid': 9, 'isLeaf': True, 'name': '文件上传', 'code': 'file', 'align': 'center'},
60
+ {'id': 15, 'sort': 13, 'pid': 7, 'isLeaf': True, 'name': '富文本', 'code': 'rich', 'align': 'center'},
61
+ {'id': 17, 'sort': 11, 'pid': 10, 'isLeaf': True, 'name': '开关', 'code': 'switch', 'align': 'center'},
62
+ {'id': 19, 'sort': 9, 'pid': 7, 'isLeaf': True, 'name': '颜色选择', 'code': 'color', 'align': 'center'},
63
+ {'id': 20, 'sort': 14, 'pid': 11, 'isLeaf': True, 'name': '穿梭框', 'code': 'transfer', 'align': 'left'},
64
+ {'id': 21, 'sort': 16, 'pid': 7, 'isLeaf': True, 'name': '自动填充', 'code': 'auto', 'align': 'left'},
65
+ {'id': 22, 'sort': 35, 'pid': 5, 'isLeaf': True, 'name': '日期选择', 'code': 'date', 'align': 'left'},
66
+ {'id': 23, 'sort': 12, 'pid': 10, 'isLeaf': True, 'name': '逻辑选择', 'code': 'boolean', 'align': 'center'},
67
+ {'id': 24, 'sort': 24, 'pid': 11, 'isLeaf': True, 'name': '列表选择', 'code': 'select', 'align': 'left'},
68
+ {'id': 25, 'sort': 15, 'pid': 11, 'isLeaf': True, 'name': '树形选择', 'code': 'tree', 'align': 'left'},
69
+ {'id': 26, 'sort': 23, 'pid': 11, 'isLeaf': True, 'name': '及联选择', 'code': 'cascade', 'align': 'left'},
70
+ {'id': 28, 'sort': 25, 'pid': 7, 'isLeaf': True, 'name': '图标', 'code': 'icon', 'align': 'center'},
71
+ {'id': 32, 'sort': 30, 'pid': 7, 'isLeaf': True, 'name': '文本框', 'code': 'textarea', 'align': 'left'},
72
+ {'id': 33, 'sort': 18, 'pid': 36, 'isLeaf': True, 'name': '时间区间', 'code': 'timerange', 'align': 'left'},
73
+ {'id': 35, 'sort': 33, 'pid': 5, 'isLeaf': True, 'name': '时间选择', 'code': 'time', 'align': 'left'},
74
+ {'id': 36, 'sort': 20, 'pid': 0, 'isLeaf': False, 'name': 'RANGE', 'code': '区间工具集'},
75
+ {'id': 37, 'sort': 38, 'pid': 36, 'isLeaf': True, 'name': '日期区间', 'code': 'daterange', 'align': 'left'},
76
+ {'id': 39, 'sort': 3, 'pid': 36, 'isLeaf': True, 'name': '多日期', 'code': 'dates', 'align': 'left'},
77
+ {'id': 54, 'sort': 54, 'pid': 7, 'isLeaf': True, 'name': '集合', 'code': 'set', 'align': 'left'},
78
+ {'id': 31, 'sort': 6, 'pid': 0, 'isLeaf': True, 'name': '无', 'code': 'none', 'align': 'left'},
79
+ ]
80
+
81
+ meta_field_tool_mapping = {
82
+ row['code']: row['align']
83
+ for row in meta_field_tool
84
+ if row['isLeaf']
85
+ }
86
+ meta_field_domain = [
87
+ {
88
+ 'name': 'CharField',
89
+ 'default_id': 'text',
90
+ 'tools': [
91
+ 'text', 'number', 'color', 'auto', 'date', 'time', 'select', 'tree', 'cascade', 'icon',
92
+ 'textarea', 'timerange', 'daterange', 'dates', 'set'
93
+ ]
94
+ },
95
+ {
96
+ 'name': 'TextField',
97
+ 'default_id': 'textarea',
98
+ 'tools': ['text', 'textarea', 'rich']
99
+ },
100
+ {
101
+ 'name': 'BooleanField',
102
+ 'default_id': 'switch',
103
+ 'tools': ['switch', 'boolean']
104
+ },
105
+ {
106
+ 'name': 'IntegerField',
107
+ 'default_id': 'number',
108
+ 'tools': ['number']
109
+ },
110
+ {
111
+ 'name': 'FloatField',
112
+ 'default_id': 'number',
113
+ 'tools': ['number']
114
+ },
115
+ {
116
+ 'name': 'ForeignKey',
117
+ 'default_id': 'select',
118
+ 'tools': ['select', 'tree', 'cascade']
119
+ },
120
+ {
121
+ 'name': 'ManyToOneRel',
122
+ 'default_id': 'select',
123
+ 'tools': ['transfer', 'select', 'tree', 'cascade']
124
+ },
125
+ {
126
+ 'name': 'ManyToManyField',
127
+ 'default_id': 'select',
128
+ 'tools': ['transfer', 'select', 'tree', 'cascade']
129
+ },
130
+ {
131
+ 'name': 'ManyToManyRel',
132
+ 'default_id': 'select',
133
+ 'tools': ['transfer', 'select', 'tree', 'cascade']
134
+ },
135
+ {
136
+ 'name': 'OneToOneRel',
137
+ 'default_id': 'select',
138
+ 'tools': ['select']
139
+ },
140
+ {
141
+ 'name': 'OneToOneField',
142
+ 'default_id': 'select',
143
+ 'tools': ['select']
144
+ },
145
+ {
146
+ 'name': 'DateField',
147
+ 'default_id': 'date',
148
+ 'tools': ['date']
149
+ },
150
+ {
151
+ 'name': 'TimeField',
152
+ 'default_id': 'time',
153
+ 'tools': ['time']
154
+ },
155
+ {
156
+ 'name': 'DateTimeField',
157
+ 'default_id': 'date',
158
+ 'tools': ['date']
159
+ },
160
+ {
161
+ 'name': 'JSONField',
162
+ 'default_id': 'object',
163
+ 'tools': ['object']
164
+ },
165
+ {
166
+ 'name': 'FileField',
167
+ 'default_id': 'file',
168
+ 'tools': ['image', 'file']
169
+ },
170
+ {
171
+ 'name': 'BigAutoField',
172
+ 'default_id': 'none',
173
+ 'tools': ['none']
174
+ },
175
+ {
176
+ 'name': 'UUIDField',
177
+ 'default_id': 'none',
178
+ 'tools': ['none']
179
+ },
180
+ {
181
+ 'name': 'Custom',
182
+ 'default_id': 'none',
183
+ 'tools': ['none']
184
+ },
185
+ ]
186
+ meta_field_domain_mapping = {
187
+ row['name']: row['default_id']
188
+ for row in meta_field_domain
189
+ }
valar/dao/meta.py ADDED
@@ -0,0 +1,128 @@
1
+ import copy
2
+
3
+ from deepmerge import always_merger
4
+ from django.conf import settings
5
+
6
+ from ..dao.defaults.field_keys_default import meta_field_key_defaults
7
+ from ..dao.defaults.field_values_default import meta_field_value_defaults
8
+ from ..dao.defaults.view_defaults import meta_view_default_values
9
+ from ..dao.abstract import AbstractDao
10
+ from ..dao.frame import meta_field_tool_mapping
11
+ from ..dao.mon_dao import MonDao
12
+ from ..dao.orm_dao import OrmDao
13
+ from ..dao.orm_field import column_width
14
+ from ..models.frame import MetaFieldDomain
15
+ from ..models.meta import Meta, MetaView
16
+
17
+
18
+ class ValarMeta:
19
+ def __init__(self, db, entity, code):
20
+ self.entity = entity
21
+ self.db = db
22
+ self.dao: AbstractDao = MonDao(entity) if db == 'mon' else OrmDao(entity)
23
+ self.code = code or 'default'
24
+
25
+ meta_dao = OrmDao('valar.Meta')
26
+ view_dao = OrmDao('valar.MetaView')
27
+ field_dao = OrmDao('valar.MetaField')
28
+
29
+ meta_item = {"entity": entity, 'db': db}
30
+ meta: Meta = meta_dao.search(meta_item).first()
31
+ if meta is None:
32
+ meta_item.update({"name": self.dao.name, 'saved': True, 'tree': self.dao.is_tree})
33
+ meta = meta_dao.save_one(meta_item)
34
+ self.meta = meta
35
+
36
+ # load_view
37
+ view_item = {"code": self.code, "meta_id": meta.id}
38
+ view: MetaView = view_dao.search(view_item).first()
39
+ if view is None:
40
+ self.__initial_view__(view_item)
41
+ view = view_dao.save_one(view_item)
42
+ self.view = view
43
+
44
+ # load_fields
45
+ if view.metafield_set.count() == 0:
46
+ _fields = self.__initial_fields__()
47
+ for _field in _fields:
48
+ if _field['prop'] not in ['sort', 'create_time', 'modify_time', 'saved']:
49
+ _field.update({'view_id': view.id, "saved": True})
50
+ field_dao.save_one(_field)
51
+
52
+ def meta_view(self):
53
+ _view = self.view.json()
54
+ meta = self.meta.json()
55
+ name, entity = meta['name'], meta['entity']
56
+ fields = self.view.metafield_set.all().order_by('-sort')
57
+ _fields = {}
58
+ _minio = settings.MINIO_ROOT if hasattr(settings, 'MINIO_ROOT') else '/minio'
59
+ for field in fields:
60
+ _field = field.json(entity=entity, code=self.code, db='orm', minio=_minio)
61
+ align, tool, width, domain = _field['align'], _field['tool'], _field['column_width'], _field['domain']
62
+ _field['align'] = align if align else meta_field_tool_mapping.get(tool, 'left')
63
+ _field['column_width'] = width if width else column_width(domain, tool)
64
+
65
+ _fields[field.prop] = _field
66
+
67
+ _minio = settings.MINIO_ROOT if hasattr(settings, 'MINIO_ROOT') else '/minio'
68
+ _view.update({
69
+ '$minio': _minio,
70
+ '$db': 'orm',
71
+ '$entity': entity,
72
+ '$code': self.code,
73
+ '$meta_name': name,
74
+ '$isTree': self.dao.is_tree,
75
+ '$fields': _fields,
76
+ '$modes': self.dao.full_props()
77
+ })
78
+ return _view
79
+
80
+ """ 默认的view设置 """
81
+
82
+ def __initial_view__(self, view_item: dict):
83
+ default_view = meta_view_default_values.get(self.entity, {})
84
+ default_values = copy.deepcopy(default_view.get('__init__', {}))
85
+ code_values = copy.deepcopy(default_view.get(self.code, {}))
86
+ view_item.update({
87
+ "name": self.code.upper(),
88
+ "saved": True,
89
+ "property": {
90
+ "value": "id",
91
+ "label": "name",
92
+ "display": "id",
93
+ "sort": "sort",
94
+ "disabled": "disabled",
95
+ "isLeaf": "isLeaf",
96
+ "icon": "icon",
97
+ "children": "children",
98
+ "pid": "pid",
99
+ }
100
+ })
101
+ values = always_merger.merge(default_values, code_values)
102
+ view_item.update(values)
103
+
104
+ def __initial_fields__(self):
105
+ default_keys = meta_field_key_defaults.get(self.entity, {})
106
+ method, array = default_keys.get(self.code, ('omit', []))
107
+
108
+ def fun(prop):
109
+ return prop not in array if method == 'omit' else prop in array
110
+
111
+ props = [prop for prop in self.dao.props() if fun(prop)]
112
+ if method == 'pick':
113
+ props = [prop for prop in array if prop in props]
114
+
115
+ default_values = copy.deepcopy(meta_field_value_defaults.get(self.entity, {}))
116
+ init_values = default_values.get('__init__', {})
117
+ code_values = default_values.get(self.code, {})
118
+ default_fields = always_merger.merge(init_values, code_values)
119
+
120
+ fields = []
121
+ for prop in props:
122
+ field = self.dao.get_meta_field(prop)
123
+ field_json = field.to_dict()
124
+ default_field = default_fields.get(prop, {})
125
+ always_merger.merge(field_json, default_field)
126
+ fields.append(field_json)
127
+ fields.reverse()
128
+ return fields
valar/dao/mon_dao.py ADDED
@@ -0,0 +1,113 @@
1
+ from pymongo.synchronous.collection import Collection
2
+ from pymongo.results import InsertOneResult
3
+ from pymongo.synchronous.cursor import Cursor
4
+
5
+ from collections import defaultdict
6
+
7
+ from .query import Query
8
+ from ..dao.abstract import AbstractDao
9
+ from ..dao.mon_field import MonField
10
+
11
+ domain_mapping = {
12
+ 'ObjectId': ('BigAutoField', 'none'),
13
+ 'int': ('CharField', 'number'),
14
+ 'str': ('TextField', 'text'),
15
+ 'float': ('CharField', 'number'),
16
+ 'bool': ('BooleanField', 'boolean'),
17
+ }
18
+
19
+
20
+ class MonDao(AbstractDao):
21
+
22
+ def __init__(self, entity):
23
+ self.db = 'mon'
24
+ self.entity = entity
25
+ self.name = entity
26
+ self.manager: Collection = self.engine.get_mongo_collection(entity)
27
+ self.is_tree = False
28
+ fields = {}
29
+ for prop, domain, tool in self.__analyze_field_types__():
30
+ fields[prop] = MonField(entity, prop, domain, tool)
31
+ self.fields = fields
32
+
33
+ def __analyze_field_types__(self):
34
+ array = []
35
+ type_map = defaultdict(set)
36
+ cursor = self.manager.find().limit(1000)
37
+ for doc in cursor:
38
+ for key, value in doc.items():
39
+ type_map[key].add(type(value).__name__)
40
+ for prop, domains in dict(type_map).items():
41
+ domain, tool = domain_mapping[domains.pop()]
42
+ prop = 'id' if prop == '_id' else prop
43
+ array.append((prop, domain, tool))
44
+ return array
45
+
46
+ def __detach_item__(self, item):
47
+ _id = item.get('id')
48
+ if _id:
49
+ del item['id']
50
+ return self.object_id(_id), item
51
+ else:
52
+ return None, item
53
+
54
+ def save_many(self, array: list):
55
+ self.manager.insert_many(array)
56
+
57
+ def values(self, conditions, props):
58
+ return None
59
+
60
+ def save_one(self, item, with_id=False):
61
+ oid, item = self.__detach_item__(item)
62
+ if oid:
63
+ self.manager.update_one({'_id': oid}, {'$set': item})
64
+ else:
65
+ bean: InsertOneResult = self.manager.insert_one(item)
66
+ oid = bean.inserted_id
67
+ self.manager.update_one({'_id': oid}, {'$set': {'sort': str(oid)}})
68
+ return self.manager.find_one({'_id': oid})
69
+
70
+ def delete_one(self, _id):
71
+ oid = self.object_id(_id)
72
+ flag = oid is not None
73
+ if flag:
74
+ self.manager.delete_one({'_id': oid})
75
+ return flag
76
+
77
+ def find_one(self, _id):
78
+ oid = self.object_id(_id)
79
+ return self.manager.find_one({'_id': oid}) if oid else None
80
+
81
+ def find(self, conditions=None, orders=None, size=0, page=1):
82
+ finder, orders = Query(conditions, orders).mon()
83
+ skip = (page - 1) * size
84
+ total = self.manager.count_documents(finder)
85
+ cursor = self.manager.find(finder).skip(skip).sort(orders)
86
+ if size:
87
+ cursor = cursor.limit(size)
88
+ return cursor, total
89
+
90
+ def update(self, template, conditions):
91
+ flag = template is not None and len(template.keys())
92
+ if flag:
93
+ oid, item = self.__detach_item__(template)
94
+ finder, _ = Query(conditions).mon()
95
+ self.manager.update_many(finder, {'$set': item})
96
+ return flag
97
+
98
+ def delete(self, conditions=None) -> list:
99
+ finder, _ = Query(conditions).mon()
100
+ self.manager.delete_many(finder)
101
+ return []
102
+
103
+ def serialize(self, o, code=None):
104
+ return [__to_item__(doc) for doc in o] if isinstance(o, Cursor) else __to_item__(o)
105
+
106
+ def tree(self, root, conditions=None):
107
+ pass
108
+
109
+
110
+ def __to_item__(o):
111
+ o['id'] = str(o['_id'])
112
+ del o['_id']
113
+ return o