valar 1.0.21__py3-none-any.whl → 1.0.22__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.
- valar/__init__.py +0 -26
- valar/channels/__init__.py +1 -107
- valar/channels/consumer.py +48 -0
- valar/channels/executer.py +13 -0
- valar/channels/mapping.py +21 -0
- valar/channels/sender.py +60 -0
- valar/channels/views.py +6 -11
- valar/core/__init__.py +0 -0
- valar/core/counter.py +9 -0
- valar/core/dao/__init__.py +0 -0
- valar/core/dao/_mon_array2tree.py +18 -0
- valar/core/dao/dao_base.py +50 -0
- valar/core/dao/dao_mon.py +76 -0
- valar/core/dao/dao_orm.py +96 -0
- valar/core/dao/engine.py +12 -0
- valar/core/dao/engine_minio.py +90 -0
- valar/core/dao/engine_mon.py +34 -0
- valar/core/dao/engine_orm.py +25 -0
- valar/core/dao/model_mon.py +24 -0
- valar/core/dao/model_orm.py +192 -0
- valar/core/dao/query_mon.py +12 -0
- valar/core/dao/query_orm.py +43 -0
- valar/core/dao/utils_orm.py +85 -0
- valar/core/dao_abstract.py +63 -0
- valar/core/meta/__init__.py +0 -0
- valar/core/meta/defaults/__init__.py +0 -0
- valar/core/meta/defaults/field_keys_default.py +17 -0
- valar/core/meta/defaults/field_values_default.py +85 -0
- valar/core/meta/defaults/frame_defaults.py +136 -0
- valar/core/meta/defaults/view_defaults.py +7 -0
- valar/core/meta/field_orm.py +144 -0
- valar/core/meta/init_meta_frame.py +30 -0
- valar/core/meta/meta_orm.py +69 -0
- valar/core/middleware.py +20 -0
- valar/core/response.py +7 -0
- valar/core/singleton_meta.py +6 -0
- valar/core/valar_models.py +82 -0
- valar/data/apps.py +22 -0
- valar/data/migrations/0001_initial.py +141 -0
- valar/data/models.py +2 -121
- valar/data/urls.py +15 -21
- valar/data/views/__init__.py +0 -0
- valar/data/views/handler.py +41 -0
- valar/data/views/rest.py +86 -0
- {valar-1.0.21.dist-info → valar-1.0.22.dist-info}/METADATA +1 -1
- valar-1.0.22.dist-info/RECORD +51 -0
- {valar-1.0.21.dist-info → valar-1.0.22.dist-info}/WHEEL +1 -1
- valar/channels/utils.py +0 -43
- valar/data/file/__init__.py +0 -91
- valar/data/handlers.py +0 -28
- valar/data/mon/__init__.py +0 -123
- valar/data/mon/query_translator.py +0 -91
- valar/data/orm/__init__.py +0 -135
- valar/data/orm/detacher.py +0 -61
- valar/data/orm/meta.py +0 -99
- valar/data/orm/meta_frame.py +0 -100
- valar/data/orm/meta_loader.py +0 -200
- valar/data/orm/values.py +0 -102
- valar/data/query.py +0 -48
- valar/data/utils.py +0 -70
- valar/data/views.py +0 -173
- valar-1.0.21.dist-info/RECORD +0 -26
- {valar-1.0.21.dist-info → valar-1.0.22.dist-info}/licenses/LICENSE +0 -0
- {valar-1.0.21.dist-info → valar-1.0.22.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
|
|
2
|
+
meta_field_tool = [
|
|
3
|
+
{'id': 2, 'sort': 32, 'pid': 7, 'isLeaf': True, 'name': '输入框', 'code': 'text'},
|
|
4
|
+
{'id': 3, 'sort': 17, 'pid': 0, 'isLeaf': False, 'name': 'SPEC', 'code': '特殊工具集'},
|
|
5
|
+
{'id': 5, 'sort': 22, 'pid': 0, 'isLeaf': False, 'name': 'DATE', 'code': '日期时间工具集'},
|
|
6
|
+
{'id': 6, 'sort': 21, 'pid': 8, 'isLeaf': True, 'name': '数字输入', 'code': 'number'},
|
|
7
|
+
{'id': 7, 'sort': 36, 'pid': 0, 'isLeaf': False, 'name': 'TEXT', 'code': '文本工具集'},
|
|
8
|
+
{'id': 8, 'sort': 26, 'pid': 0, 'isLeaf': False, 'name': 'NUMB', 'code': '数字工具集'},
|
|
9
|
+
{'id': 9, 'sort': 10, 'pid': 0, 'isLeaf': False, 'name': 'FILE', 'code': '文件工具集'},
|
|
10
|
+
{'id': 10, 'sort': 27, 'pid': 0, 'isLeaf': False, 'name': 'BOOL', 'code': '逻辑工具集'},
|
|
11
|
+
{'id': 11, 'sort': 31, 'pid': 0, 'isLeaf': False, 'name': 'LIST', 'code': '列表工具集'},
|
|
12
|
+
{'id': 12, 'sort': 8, 'pid': 3, 'isLeaf': True, 'name': '对象', 'code': 'object'},
|
|
13
|
+
{'id': 13, 'sort': 5, 'pid': 9, 'isLeaf': True, 'name': '图片上传', 'code': 'image'},
|
|
14
|
+
{'id': 14, 'sort': 2, 'pid': 9, 'isLeaf': True, 'name': '文件上传', 'code': 'file'},
|
|
15
|
+
{'id': 15, 'sort': 13, 'pid': 9, 'isLeaf': True, 'name': '富文本', 'code': 'rich'},
|
|
16
|
+
{'id': 17, 'sort': 11, 'pid': 10, 'isLeaf': True, 'name': '开关', 'code': 'switch'},
|
|
17
|
+
{'id': 18, 'sort': 7, 'pid': 3, 'isLeaf': True, 'name': '元数据', 'code': 'meta'},
|
|
18
|
+
{'id': 19, 'sort': 9, 'pid': 7, 'isLeaf': True, 'name': '颜色选择', 'code': 'color'},
|
|
19
|
+
{'id': 20, 'sort': 14, 'pid': 11, 'isLeaf': True, 'name': '穿梭框', 'code': 'transfer'},
|
|
20
|
+
{'id': 21, 'sort': 16, 'pid': 7, 'isLeaf': True, 'name': '自动填充', 'code': 'auto'},
|
|
21
|
+
{'id': 22, 'sort': 35, 'pid': 5, 'isLeaf': True, 'name': '日期选择', 'code': 'date'},
|
|
22
|
+
{'id': 23, 'sort': 12, 'pid': 10, 'isLeaf': True, 'name': '逻辑选择', 'code': 'boolean'},
|
|
23
|
+
{'id': 24, 'sort': 24, 'pid': 11, 'isLeaf': True, 'name': '列表选择', 'code': 'select'},
|
|
24
|
+
{'id': 25, 'sort': 15, 'pid': 11, 'isLeaf': True, 'name': '树形选择', 'code': 'tree'},
|
|
25
|
+
{'id': 26, 'sort': 23, 'pid': 11, 'isLeaf': True, 'name': '及联选择', 'code': 'cascade'},
|
|
26
|
+
{'id': 28, 'sort': 25, 'pid': 7, 'isLeaf': True, 'name': '图标', 'code': 'icon'},
|
|
27
|
+
{'id': 31, 'sort': 6, 'pid': 0, 'isLeaf': True, 'name': '无', 'code': 'none'},
|
|
28
|
+
{'id': 32, 'sort': 30, 'pid': 7, 'isLeaf': True, 'name': '文本框', 'code': 'textarea'},
|
|
29
|
+
{'id': 33, 'sort': 18, 'pid': 36, 'isLeaf': True, 'name': '时间区间', 'code': 'timerange'},
|
|
30
|
+
{'id': 35, 'sort': 33, 'pid': 5, 'isLeaf': True, 'name': '时间选择', 'code': 'time'},
|
|
31
|
+
{'id': 36, 'sort': 20, 'pid': 0, 'isLeaf': False, 'name': 'RANGE', 'code': '区间工具集'},
|
|
32
|
+
{'id': 37, 'sort': 38, 'pid': 36, 'isLeaf': True, 'name': '日期区间', 'code': 'daterange'},
|
|
33
|
+
{'id': 39, 'sort': 3, 'pid': 36, 'isLeaf': True, 'name': '多日期', 'code': 'dates'},
|
|
34
|
+
{'id': 54, 'sort': 54, 'pid': 7, 'isLeaf': True, 'name': '集合', 'code': 'set'}
|
|
35
|
+
]
|
|
36
|
+
|
|
37
|
+
meta_field_domain = [
|
|
38
|
+
{
|
|
39
|
+
'name': 'CharField',
|
|
40
|
+
'default_id': 'text', 'align': 'left',
|
|
41
|
+
'tools': [
|
|
42
|
+
'text', 'number', 'meta', 'color', 'auto', 'date', 'select', 'tree', 'cascade', 'icon',
|
|
43
|
+
'textarea', 'timerange', 'daterange', 'dates', 'set'
|
|
44
|
+
]
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
'name': 'TextField',
|
|
48
|
+
'default_id': 'textarea', 'align': 'left',
|
|
49
|
+
'tools': ['text', 'textarea']
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
'name': 'BooleanField',
|
|
53
|
+
'default_id': 'switch', 'align': 'center',
|
|
54
|
+
'tools': ['switch', 'boolean']
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
'name': 'IntegerField',
|
|
58
|
+
'default_id': 'number', 'align': 'right',
|
|
59
|
+
'tools': ['number']
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
'name': 'FloatField',
|
|
63
|
+
'default_id': 'number', 'align': 'right',
|
|
64
|
+
'tools': ['number']
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
'name': 'ForeignKey',
|
|
68
|
+
'default_id': 'select', 'align': 'left',
|
|
69
|
+
'tools': ['select', 'tree', 'cascade']
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
'name': 'ManyToOneRel',
|
|
73
|
+
'default_id': 'select', 'align': 'center',
|
|
74
|
+
'tools': ['transfer', 'select', 'tree', 'cascade']
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
'name': 'ManyToManyField',
|
|
78
|
+
'default_id': 'select', 'align': 'center',
|
|
79
|
+
'tools': [ 'transfer', 'select', 'tree', 'cascade']
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
'name': 'ManyToManyRel',
|
|
83
|
+
'default_id': 'select', 'align': 'center',
|
|
84
|
+
'tools': ['transfer', 'select', 'tree', 'cascade']
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
'name': 'OneToOneRel',
|
|
88
|
+
'default_id': 'none', 'align': 'left',
|
|
89
|
+
'tools': []
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
'name': 'OneToOneField',
|
|
93
|
+
'default_id': 'none', 'align': 'left',
|
|
94
|
+
'tools': []
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
'name': 'DateField',
|
|
98
|
+
'default_id': 'date', 'align': 'center',
|
|
99
|
+
'tools': ['date']
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
'name': 'TimeField',
|
|
103
|
+
'default_id': 'time', 'align': 'center',
|
|
104
|
+
'tools': ['time']
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
'name': 'DateTimeField',
|
|
108
|
+
'default_id': 'date', 'align': 'center',
|
|
109
|
+
'tools': ['date']
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
'name': 'JSONField',
|
|
113
|
+
'default_id': 'object', 'align': 'center',
|
|
114
|
+
'tools': ['object']
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
'name': 'FileField',
|
|
118
|
+
'default_id': 'file', 'align': 'center',
|
|
119
|
+
'tools': ['image', 'file', 'rich']
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
'name': 'BigAutoField',
|
|
123
|
+
'default_id': 'none', 'align': 'right',
|
|
124
|
+
'tools': []
|
|
125
|
+
},
|
|
126
|
+
{
|
|
127
|
+
'name': 'UUIDField',
|
|
128
|
+
'default_id': 'none', 'align': 'left',
|
|
129
|
+
'tools': []
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
'name': 'Custom',
|
|
133
|
+
'default_id': 'none', 'align': 'left',
|
|
134
|
+
'tools': []
|
|
135
|
+
},
|
|
136
|
+
]
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
from deepmerge import always_merger
|
|
2
|
+
from django.db.models import ManyToOneRel, ForeignKey, ManyToManyRel, ManyToManyField,OneToOneField,OneToOneRel
|
|
3
|
+
from django.db.models import IntegerField, BooleanField, FloatField,TextField, CharField
|
|
4
|
+
from django.db.models import FileField, JSONField
|
|
5
|
+
from django.db.models import DateTimeField, TimeField, DateField
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OrmField:
|
|
10
|
+
|
|
11
|
+
def __init__(self, entity, field, is_tree):
|
|
12
|
+
self.entity = entity
|
|
13
|
+
self.model_field = field
|
|
14
|
+
self.is_tree = is_tree
|
|
15
|
+
self.not_null = not field.null
|
|
16
|
+
self.clazz = type(field)
|
|
17
|
+
self.multiple = self.clazz in [ManyToOneRel, ManyToManyField, ManyToManyRel]
|
|
18
|
+
|
|
19
|
+
self.prop = self.__prop__()
|
|
20
|
+
self.domain = self.__domain__()
|
|
21
|
+
self.model = self.__model__()
|
|
22
|
+
self.label = self.__label__()
|
|
23
|
+
self.column_width = self.__column_width__()
|
|
24
|
+
self.refer = self.__refer__()
|
|
25
|
+
self.align = self.___align__()
|
|
26
|
+
self.format = self.__formating__()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def json(self):
|
|
33
|
+
_field = {
|
|
34
|
+
"prop": self.prop,
|
|
35
|
+
"label": self.label,
|
|
36
|
+
"name": self.label,
|
|
37
|
+
"domain": self.domain,
|
|
38
|
+
"refer": self.refer,
|
|
39
|
+
"format": self.format,
|
|
40
|
+
"not_null": self.not_null,
|
|
41
|
+
"align": self.align,
|
|
42
|
+
"column_width": self.column_width,
|
|
43
|
+
}
|
|
44
|
+
if self.is_tree:
|
|
45
|
+
if self.prop in ['pid', 'isLeaf']:
|
|
46
|
+
_field['hide_on_table'] = True
|
|
47
|
+
_field['hide_on_form'] = True
|
|
48
|
+
_field['hide_on_form_branch'] = True
|
|
49
|
+
_field['hide_on_form_leaf'] = True
|
|
50
|
+
elif self.prop in ['icon']:
|
|
51
|
+
_field['tool'] = 'icon'
|
|
52
|
+
return _field
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def __column_width__(self):
|
|
56
|
+
if self.clazz in [BooleanField, FileField, JSONField]:
|
|
57
|
+
return 100
|
|
58
|
+
elif self.clazz in [DateField, DateTimeField, TimeField]:
|
|
59
|
+
return 120
|
|
60
|
+
return 0
|
|
61
|
+
|
|
62
|
+
def __label__(self):
|
|
63
|
+
return self.model._meta.verbose_name \
|
|
64
|
+
if self.clazz in [ManyToOneRel, ManyToManyField, ManyToManyRel, OneToOneRel, OneToOneField] \
|
|
65
|
+
else self.model_field.verbose_name
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def __model__(self):
|
|
69
|
+
return self.model_field.related_model \
|
|
70
|
+
if self.clazz in [ManyToOneRel, ManyToManyField, ManyToManyRel, OneToOneRel, OneToOneField, ForeignKey] \
|
|
71
|
+
else None
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def __domain__(self):
|
|
75
|
+
return self.clazz.__name__ \
|
|
76
|
+
if self.clazz in [ManyToOneRel, ManyToManyField, ManyToManyRel ,OneToOneRel, OneToOneField] \
|
|
77
|
+
else self.model_field.get_internal_type()
|
|
78
|
+
|
|
79
|
+
def __prop__(self):
|
|
80
|
+
return self.model_field.name + "_id" \
|
|
81
|
+
if self.clazz in [ForeignKey,OneToOneRel, OneToOneField] \
|
|
82
|
+
else self.model_field.name
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def ___align__(self):
|
|
86
|
+
if self.clazz in [FloatField, IntegerField]:
|
|
87
|
+
return 'right'
|
|
88
|
+
elif self.clazz in [BooleanField, FileField, JSONField, DateField, DateTimeField, TimeField]:
|
|
89
|
+
return 'center'
|
|
90
|
+
return 'left'
|
|
91
|
+
|
|
92
|
+
def __refer__(self):
|
|
93
|
+
refer = {
|
|
94
|
+
"entity": None,
|
|
95
|
+
"value": "name", "label": 'name', "display": "id",
|
|
96
|
+
"multiple": self.multiple, "strict": False, "remote": False,
|
|
97
|
+
"includes": {}, "excludes": {},
|
|
98
|
+
"root": 0, "isTree": self.is_tree
|
|
99
|
+
}
|
|
100
|
+
if self.model:
|
|
101
|
+
module, name = self.model.__module__, self.model.__name__
|
|
102
|
+
refer['entity'] = '%s.%s' % (module.replace('.models', '').split('.')[-1], name)
|
|
103
|
+
return refer
|
|
104
|
+
|
|
105
|
+
def __formating__(self):
|
|
106
|
+
_format = {
|
|
107
|
+
# 文本
|
|
108
|
+
"maxlength": 0,
|
|
109
|
+
"type": 'text',
|
|
110
|
+
|
|
111
|
+
# 数值
|
|
112
|
+
"min": None,
|
|
113
|
+
"max": None,
|
|
114
|
+
"step": 1,
|
|
115
|
+
"precision": None,
|
|
116
|
+
"step_strictly": False,
|
|
117
|
+
|
|
118
|
+
# 日期
|
|
119
|
+
"frequency": "date",
|
|
120
|
+
|
|
121
|
+
# 文件
|
|
122
|
+
"maximum": 5,
|
|
123
|
+
"accept": [],
|
|
124
|
+
"width": 800,
|
|
125
|
+
"height": 0,
|
|
126
|
+
"file_name_field":None,
|
|
127
|
+
"locked": False,
|
|
128
|
+
|
|
129
|
+
#集合
|
|
130
|
+
"set": {}
|
|
131
|
+
}
|
|
132
|
+
if self.clazz == CharField:
|
|
133
|
+
_format['maxlength'] = self.model_field.max_length
|
|
134
|
+
if self.clazz == TextField:
|
|
135
|
+
_format['type'] = "textarea"
|
|
136
|
+
elif self.clazz == DateTimeField:
|
|
137
|
+
_format['frequency'] = "datetime"
|
|
138
|
+
elif self.clazz == IntegerField:
|
|
139
|
+
_format['precision'] = 0
|
|
140
|
+
_format['step_strictly'] = True
|
|
141
|
+
return _format
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import copy
|
|
2
|
+
|
|
3
|
+
from .defaults.frame_defaults import meta_field_tool, meta_field_domain
|
|
4
|
+
|
|
5
|
+
from ...data.models import MetaFieldDomain, MetaFieldTool
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def init_meta_frame():
|
|
9
|
+
from ..dao.dao_orm import OrmDao
|
|
10
|
+
tool_dao = OrmDao('data.MetaFieldTool')
|
|
11
|
+
domain_dao = OrmDao('data.MetaFieldDomain')
|
|
12
|
+
mapping = {}
|
|
13
|
+
for item in meta_field_tool:
|
|
14
|
+
_id, code = item['id'], item['code']
|
|
15
|
+
item.update({"saved": True})
|
|
16
|
+
if item['isLeaf']:
|
|
17
|
+
mapping[code] = _id
|
|
18
|
+
tool_dao.save_one(item)
|
|
19
|
+
|
|
20
|
+
for row in meta_field_domain:
|
|
21
|
+
default_id, tools = row['default_id'], row['tools']
|
|
22
|
+
print(mapping[default_id])
|
|
23
|
+
_row = copy.deepcopy(row)
|
|
24
|
+
_row.update({
|
|
25
|
+
'default_id': mapping[default_id],
|
|
26
|
+
'tools': [mapping[tool] for tool in tools],
|
|
27
|
+
"saved": True
|
|
28
|
+
})
|
|
29
|
+
domain_dao.save_one(_row)
|
|
30
|
+
return MetaFieldDomain.objects.all()
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
from deepmerge import always_merger
|
|
2
|
+
|
|
3
|
+
from .defaults.view_defaults import meta_view_default_values
|
|
4
|
+
from ...core.dao.dao_orm import OrmDao
|
|
5
|
+
from ...data.models import MetaView, Meta
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class OrmMeta:
|
|
9
|
+
|
|
10
|
+
def __init__(self, entity, code):
|
|
11
|
+
self.entity = entity
|
|
12
|
+
self.dao = OrmDao(entity)
|
|
13
|
+
self.code = code or 'default'
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# load_meta
|
|
17
|
+
meta_dao = OrmDao('data.Meta')
|
|
18
|
+
_meta = {"entity": entity}
|
|
19
|
+
meta: Meta = meta_dao.search(_meta).first()
|
|
20
|
+
if meta is None:
|
|
21
|
+
_meta.update({"name": self.dao.model.name, 'saved': True})
|
|
22
|
+
meta = meta_dao.save_one(_meta)
|
|
23
|
+
self.meta = meta
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
# load_view
|
|
27
|
+
view_dao = OrmDao('data.MetaView')
|
|
28
|
+
_view = {"code": self.code, "meta_id": meta.id}
|
|
29
|
+
view: MetaView = view_dao.search(_view).first()
|
|
30
|
+
if view is None:
|
|
31
|
+
_view.update({"name": self.code.upper(), "saved": True})
|
|
32
|
+
view = view_dao.save_one(_view)
|
|
33
|
+
self.__init_view__(view)
|
|
34
|
+
self.view = view
|
|
35
|
+
|
|
36
|
+
# load_fields
|
|
37
|
+
if view.metafield_set.count() == 0:
|
|
38
|
+
field_dao = OrmDao('data.MetaField')
|
|
39
|
+
_fields = self.dao.model.initial_fields(code)
|
|
40
|
+
for _field in _fields:
|
|
41
|
+
_field.update({'view_id':view.id, "saved": True })
|
|
42
|
+
field_dao.save_one(_field)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_view(self):
|
|
46
|
+
_view = self.view.json()
|
|
47
|
+
meta = self.meta.json()
|
|
48
|
+
name, entity = meta['name'], meta['entity']
|
|
49
|
+
fields = self.view.metafield_set.all().order_by('-sort')
|
|
50
|
+
_fields = {field.prop: field.json(entity=entity, code=self.code, db='orm') for field in fields}
|
|
51
|
+
_view.update({
|
|
52
|
+
'$db': 'orm',
|
|
53
|
+
'$entity': entity,
|
|
54
|
+
'$code': self.code,
|
|
55
|
+
'$meta_name': name,
|
|
56
|
+
'$is_tree': self.dao.model.is_tree,
|
|
57
|
+
'$fields': _fields
|
|
58
|
+
})
|
|
59
|
+
return _view
|
|
60
|
+
|
|
61
|
+
def __init_view__(self, view: MetaView):
|
|
62
|
+
default_view = meta_view_default_values.get(self.entity, {})
|
|
63
|
+
default_values = default_view.get('__init__',{})
|
|
64
|
+
code_values = default_view.get(self.code, {})
|
|
65
|
+
values = always_merger.merge(default_values, code_values)
|
|
66
|
+
if len(values) > 0:
|
|
67
|
+
for key, value in values.items():
|
|
68
|
+
setattr(view, key, value)
|
|
69
|
+
view.save()
|
valar/core/middleware.py
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
from django.http import HttpRequest
|
|
2
|
+
from django.utils.deprecation import MiddlewareMixin
|
|
3
|
+
from response import ValarResponse
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class Middleware(MiddlewareMixin):
|
|
7
|
+
@staticmethod
|
|
8
|
+
def process_response(request: HttpRequest, response: ValarResponse):
|
|
9
|
+
headers = response.headers
|
|
10
|
+
if type(response)==ValarResponse:
|
|
11
|
+
message, code = response.message, response.code
|
|
12
|
+
headers['valar_message'] = message
|
|
13
|
+
headers['valar_code'] = code
|
|
14
|
+
|
|
15
|
+
keys = ['client','auth','uid']
|
|
16
|
+
for key in keys:
|
|
17
|
+
value = request.headers.get(key)
|
|
18
|
+
if value:
|
|
19
|
+
headers[key] = value
|
|
20
|
+
return response
|
valar/core/response.py
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
from django.apps import AppConfig
|
|
2
|
+
from django.db import models
|
|
3
|
+
from django.db.models import ManyToOneRel, OneToOneRel, ManyToManyRel, ManyToManyField, UUIDField, FileField, \
|
|
4
|
+
ForeignKey, OneToOneField, DateField, TimeField, DateTimeField, BigAutoField
|
|
5
|
+
from django.db.models.options import Options
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class VModel(models.Model):
|
|
9
|
+
objects = models.Manager()
|
|
10
|
+
sort = models.BigIntegerField(null=True, verbose_name='序号')
|
|
11
|
+
name = models.CharField(max_length=50, null=True)
|
|
12
|
+
create_time = models.DateTimeField(auto_now_add=True, null=True, verbose_name='创建时间')
|
|
13
|
+
modify_time = models.DateTimeField(auto_now=True, null=True, verbose_name='修改时间')
|
|
14
|
+
saved = models.BooleanField(default=False)
|
|
15
|
+
|
|
16
|
+
class Meta:
|
|
17
|
+
abstract = True
|
|
18
|
+
|
|
19
|
+
def __str__(self):
|
|
20
|
+
return str(self.full())
|
|
21
|
+
|
|
22
|
+
def get_meta(self)->Options:
|
|
23
|
+
return getattr(self, '_meta')
|
|
24
|
+
|
|
25
|
+
def get_entity(self):
|
|
26
|
+
name = type(self).__name__
|
|
27
|
+
config: AppConfig = self.get_meta().app_config
|
|
28
|
+
return f'{config.label}.{name}'
|
|
29
|
+
|
|
30
|
+
def json(self, *args, **kwargs):
|
|
31
|
+
excludes = [ManyToOneRel, OneToOneRel, ManyToManyField, ManyToManyRel, UUIDField]
|
|
32
|
+
fields = [field for field in self.get_meta().get_fields() if type(field) not in excludes]
|
|
33
|
+
data = {}
|
|
34
|
+
for field in fields:
|
|
35
|
+
value = field.value_from_object(self)
|
|
36
|
+
prop = field.name
|
|
37
|
+
domain = type(field)
|
|
38
|
+
if value is not None:
|
|
39
|
+
if domain in [ForeignKey, OneToOneField]:
|
|
40
|
+
prop = f'{prop}_id'
|
|
41
|
+
elif domain in [DateTimeField]:
|
|
42
|
+
value = value.strftime('%Y-%m-%d %H:%M:%S')
|
|
43
|
+
elif domain in [DateField]:
|
|
44
|
+
value = value.strftime('%Y-%m-%d')
|
|
45
|
+
elif domain in [TimeField]:
|
|
46
|
+
value = value.strftime('%H:%M:%S')
|
|
47
|
+
elif domain in [FileField]:
|
|
48
|
+
value = value.name
|
|
49
|
+
elif domain in [BigAutoField]:
|
|
50
|
+
value = str(value)
|
|
51
|
+
data[prop] = value
|
|
52
|
+
data.update({f'${k}': v for k,v in kwargs.items()})
|
|
53
|
+
return data
|
|
54
|
+
|
|
55
|
+
def full(self):
|
|
56
|
+
includes = [ManyToManyField, ManyToManyRel, ForeignKey, ManyToOneRel, OneToOneField, OneToOneRel]
|
|
57
|
+
fields = [field for field in self.get_meta().get_fields() if type(field) in includes]
|
|
58
|
+
data = self.json()
|
|
59
|
+
for field in fields:
|
|
60
|
+
prop = field.name
|
|
61
|
+
domain = type(field)
|
|
62
|
+
if domain in [ForeignKey,OneToOneField]:
|
|
63
|
+
bean: VModel = getattr(self, prop)
|
|
64
|
+
data[prop] = bean.json() if bean else None
|
|
65
|
+
elif domain == OneToOneRel:
|
|
66
|
+
print('OneToOneRel')
|
|
67
|
+
pass
|
|
68
|
+
elif domain in [ManyToManyField,ManyToManyRel,ManyToOneRel]:
|
|
69
|
+
accessor = prop if domain == ManyToManyField else field.get_accessor_name()
|
|
70
|
+
_set = getattr(self, accessor).all().order_by('-sort')
|
|
71
|
+
data[prop] = [item.id for item in _set]
|
|
72
|
+
data[f'{prop}_set'] = [item.json() for item in _set]
|
|
73
|
+
return data
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
class VTree(VModel):
|
|
77
|
+
pid = models.IntegerField(null=False, default=0, verbose_name='父节点')
|
|
78
|
+
isLeaf = models.BooleanField( default=False, verbose_name='叶子节点')
|
|
79
|
+
icon = models.CharField(max_length=255, null=True, verbose_name='图标')
|
|
80
|
+
class Meta:
|
|
81
|
+
abstract = True
|
|
82
|
+
|
valar/data/apps.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import importlib
|
|
2
|
+
import os
|
|
3
|
+
|
|
4
|
+
from django.apps import AppConfig
|
|
5
|
+
from django.conf import settings
|
|
6
|
+
from django.urls import include, path
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DataConfig(AppConfig):
|
|
10
|
+
default_auto_field = 'django.db.models.BigAutoField'
|
|
11
|
+
name = 'src.valar.data'
|
|
12
|
+
|
|
13
|
+
def ready(self):
|
|
14
|
+
run_once = os.environ.get('CMDLINERUNNER_RUN_ONCE')
|
|
15
|
+
if run_once is None:
|
|
16
|
+
os.environ['CMDLINERUNNER_RUN_ONCE'] = 'True'
|
|
17
|
+
root = settings.ROOT_URLCONF
|
|
18
|
+
module = importlib.import_module(root)
|
|
19
|
+
urlpatterns = getattr(module,'urlpatterns')
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|