brilliance-admin 0.44.7__py3-none-any.whl → 0.44.9__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.
- brilliance_admin/integrations/sqlalchemy/table/retrieve.py +1 -1
- brilliance_admin/integrations/sqlalchemy/table/update.py +3 -1
- brilliance_admin/schema/table/fields/base.py +44 -5
- brilliance_admin/static/{index-BV43pxcV.js → index-DToqsJy6.js} +140 -140
- brilliance_admin/templates/index.html +1 -1
- {brilliance_admin-0.44.7.dist-info → brilliance_admin-0.44.9.dist-info}/METADATA +9 -2
- {brilliance_admin-0.44.7.dist-info → brilliance_admin-0.44.9.dist-info}/RECORD +10 -10
- {brilliance_admin-0.44.7.dist-info → brilliance_admin-0.44.9.dist-info}/WHEEL +0 -0
- {brilliance_admin-0.44.7.dist-info → brilliance_admin-0.44.9.dist-info}/licenses/LICENSE +0 -0
- {brilliance_admin-0.44.7.dist-info → brilliance_admin-0.44.9.dist-info}/top_level.txt +0 -0
|
@@ -23,7 +23,7 @@ class SQLAlchemyAdminRetrieveMixin:
|
|
|
23
23
|
language_context: LanguageContext,
|
|
24
24
|
admin_schema: AdminSchema,
|
|
25
25
|
) -> schema.RetrieveResult:
|
|
26
|
-
if not self.
|
|
26
|
+
if not self.has_retrieve:
|
|
27
27
|
raise AdminAPIException(APIError(message=_('errors.method_not_allowed')), status_code=500)
|
|
28
28
|
|
|
29
29
|
# pylint: disable=import-outside-toplevel
|
|
@@ -85,7 +85,9 @@ class SQLAlchemyAdminUpdate:
|
|
|
85
85
|
type(self).__name__, self.table_schema.model.__name__, pk, e,
|
|
86
86
|
extra={'data': data}
|
|
87
87
|
)
|
|
88
|
-
msg = _('errors.db_error_update') % {
|
|
88
|
+
msg = _('errors.db_error_update') % {
|
|
89
|
+
'error_type': str(e) if admin_schema.debug else type(e).__name__,
|
|
90
|
+
}
|
|
89
91
|
raise AdminAPIException(
|
|
90
92
|
APIError(message=msg, code='db_error_update'), status_code=500,
|
|
91
93
|
) from e
|
|
@@ -127,6 +127,18 @@ class BooleanField(TableField):
|
|
|
127
127
|
_type = 'boolean'
|
|
128
128
|
|
|
129
129
|
|
|
130
|
+
def _parse_iso(value: str) -> datetime.datetime:
|
|
131
|
+
if value.endswith('Z'):
|
|
132
|
+
value = value.replace('Z', '+00:00')
|
|
133
|
+
|
|
134
|
+
dt = datetime.datetime.fromisoformat(value)
|
|
135
|
+
|
|
136
|
+
if dt.tzinfo is None:
|
|
137
|
+
dt = dt.replace(tzinfo=datetime.timezone.utc)
|
|
138
|
+
|
|
139
|
+
return dt
|
|
140
|
+
|
|
141
|
+
|
|
130
142
|
@dataclass
|
|
131
143
|
class DateTimeField(TableField):
|
|
132
144
|
_type = 'datetime'
|
|
@@ -155,16 +167,17 @@ class DateTimeField(TableField):
|
|
|
155
167
|
raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
|
|
156
168
|
|
|
157
169
|
if isinstance(value, str):
|
|
158
|
-
return
|
|
170
|
+
return _parse_iso(value)
|
|
159
171
|
|
|
160
172
|
if isinstance(value, dict):
|
|
161
173
|
if not value.get('from') or not value.get('to'):
|
|
162
|
-
|
|
163
|
-
|
|
174
|
+
raise FieldError(
|
|
175
|
+
f'{type(self).__name__} value must be dict with from,to values: {value}'
|
|
176
|
+
)
|
|
164
177
|
|
|
165
178
|
return {
|
|
166
|
-
'from':
|
|
167
|
-
'to':
|
|
179
|
+
'from': _parse_iso(value['from']),
|
|
180
|
+
'to': _parse_iso(value['to']),
|
|
168
181
|
}
|
|
169
182
|
|
|
170
183
|
raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
|
|
@@ -291,3 +304,29 @@ class ChoiceField(TableField):
|
|
|
291
304
|
'value': value,
|
|
292
305
|
'title': choice.get('title') or value if choice else value.capitalize(),
|
|
293
306
|
}
|
|
307
|
+
|
|
308
|
+
async def deserialize(self, value, action: DeserializeAction, extra: dict, *args, **kwargs) -> Any:
|
|
309
|
+
value = await super().deserialize(value, action, extra, *args, **kwargs)
|
|
310
|
+
|
|
311
|
+
if value is None:
|
|
312
|
+
return
|
|
313
|
+
|
|
314
|
+
if isinstance(value, dict):
|
|
315
|
+
if 'value' not in value:
|
|
316
|
+
raise FieldError(
|
|
317
|
+
f'{type(self).__name__} dict value must contain "value": {value}'
|
|
318
|
+
)
|
|
319
|
+
value = value['value']
|
|
320
|
+
|
|
321
|
+
if not isinstance(value, str):
|
|
322
|
+
raise FieldError(
|
|
323
|
+
f'{type(self).__name__} value must be str, got {type(value)}'
|
|
324
|
+
)
|
|
325
|
+
|
|
326
|
+
choice = self.find_choice(value)
|
|
327
|
+
if not choice:
|
|
328
|
+
raise FieldError(
|
|
329
|
+
f'Invalid choice value "{value}", allowed: {[c["value"] for c in self.choices or []]}'
|
|
330
|
+
)
|
|
331
|
+
|
|
332
|
+
return value
|