educommon 3.12.0__py3-none-any.whl → 3.13.2__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.
Files changed (221) hide show
  1. educommon/__init__.py +0 -1
  2. educommon/about/ui/actions.py +16 -30
  3. educommon/about/ui/ui.py +3 -12
  4. educommon/about/utils.py +6 -5
  5. educommon/async_task/__init__.py +0 -1
  6. educommon/async_task/actions.py +18 -13
  7. educommon/async_task/apps.py +4 -0
  8. educommon/async_task/locker.py +2 -5
  9. educommon/async_task/migrations/0001_initial.py +55 -9
  10. educommon/async_task/migrations/0002_task_type_and_status_data.py +94 -89
  11. educommon/async_task/migrations/0003_alter_runningtask_options.py +0 -1
  12. educommon/async_task/models.py +9 -6
  13. educommon/async_task/tasks.py +11 -7
  14. educommon/async_task/ui.py +16 -35
  15. educommon/async_tasks/__init__.py +0 -1
  16. educommon/async_tasks/apps.py +4 -0
  17. educommon/async_tasks/locks.py +11 -21
  18. educommon/async_tasks/migrations/0001_initial.py +68 -8
  19. educommon/async_tasks/migrations/0002_load_initial_data.py +0 -1
  20. educommon/async_tasks/models.py +9 -29
  21. educommon/async_tasks/tasks.py +25 -54
  22. educommon/audit_log/__init__.py +1 -0
  23. educommon/audit_log/actions.py +27 -36
  24. educommon/audit_log/app_meta.py +7 -4
  25. educommon/audit_log/apps.py +44 -29
  26. educommon/audit_log/constants.py +7 -4
  27. educommon/audit_log/error_log/actions.py +1 -3
  28. educommon/audit_log/helpers.py +2 -4
  29. educommon/audit_log/management/commands/reinstall_audit_log.py +11 -7
  30. educommon/audit_log/migrations/0001_initial.py +91 -16
  31. educommon/audit_log/migrations/0002_install_audit_log.py +13 -13
  32. educommon/audit_log/migrations/0003_logproxy.py +1 -3
  33. educommon/audit_log/migrations/0004_reinstall_audit_log.py +1 -4
  34. educommon/audit_log/migrations/0005_postgresql_error.py +4 -2
  35. educommon/audit_log/migrations/0006_auto_20200806_1707.py +3 -4
  36. educommon/audit_log/migrations/0007_create_selective_tables_function.py +8 -5
  37. educommon/audit_log/migrations/0008_table_logged.py +0 -1
  38. educommon/audit_log/migrations/0009_reinstall_audit_log.py +0 -1
  39. educommon/audit_log/models.py +36 -42
  40. educommon/audit_log/permissions.py +11 -9
  41. educommon/audit_log/proxies.py +12 -23
  42. educommon/audit_log/ui.py +18 -15
  43. educommon/audit_log/utils/__init__.py +28 -60
  44. educommon/audit_log/utils/operations.py +16 -2
  45. educommon/auth/__init__.py +0 -3
  46. educommon/auth/rbac/__init__.py +2 -4
  47. educommon/auth/rbac/actions.py +148 -145
  48. educommon/auth/rbac/app_meta.py +9 -6
  49. educommon/auth/rbac/backends/base.py +2 -8
  50. educommon/auth/rbac/backends/caching.py +27 -37
  51. educommon/auth/rbac/backends/simple.py +1 -4
  52. educommon/auth/rbac/checker.py +1 -3
  53. educommon/auth/rbac/management/commands/rbac.py +6 -11
  54. educommon/auth/rbac/manager.py +18 -47
  55. educommon/auth/rbac/migrations/0001_initial.py +73 -12
  56. educommon/auth/rbac/migrations/0002_model_modifier_metaclass_fix.py +7 -6
  57. educommon/auth/rbac/migrations/0003_permission_hidden.py +1 -5
  58. educommon/auth/rbac/migrations/0004_auto_20171024_1245.py +26 -19
  59. educommon/auth/rbac/models.py +63 -68
  60. educommon/auth/rbac/permissions.py +6 -7
  61. educommon/auth/rbac/ui.py +83 -84
  62. educommon/auth/rbac/utils.py +10 -11
  63. educommon/auth/rbac/validators.py +4 -5
  64. educommon/auth/simple_auth/__init__.py +1 -5
  65. educommon/auth/simple_auth/actions.py +79 -92
  66. educommon/auth/simple_auth/app_meta.py +2 -9
  67. educommon/auth/simple_auth/checkers.py +3 -3
  68. educommon/auth/simple_auth/migrations/0001_initial.py +23 -4
  69. educommon/auth/simple_auth/validators.py +0 -1
  70. educommon/contingent/actions.py +7 -7
  71. educommon/contingent/app_meta.py +1 -4
  72. educommon/contingent/base.py +10 -15
  73. educommon/contingent/catalogs.py +424 -540
  74. educommon/contingent/contingent_plugin/actions.py +4 -15
  75. educommon/contingent/contingent_plugin/apps.py +10 -4
  76. educommon/contingent/contingent_plugin/migrations/0001_initial.py +5 -6
  77. educommon/contingent/contingent_plugin/migrations/0002_add_contingent_model_deleted.py +6 -11
  78. educommon/contingent/contingent_plugin/model_views.py +2 -12
  79. educommon/contingent/contingent_plugin/models.py +2 -7
  80. educommon/contingent/contingent_plugin/observer.py +14 -13
  81. educommon/contingent/contingent_plugin/plugin_meta.py +1 -3
  82. educommon/contingent/contingent_plugin/storage.py +8 -7
  83. educommon/contingent/contingent_plugin/utils.py +6 -6
  84. educommon/django/db/fields.py +72 -86
  85. educommon/django/db/migration/__init__.py +3 -7
  86. educommon/django/db/migration/operations.py +29 -51
  87. educommon/django/db/mixins/__init__.py +16 -10
  88. educommon/django/db/mixins/date_interval.py +47 -75
  89. educommon/django/db/mixins/validation.py +26 -26
  90. educommon/django/db/model_view/__init__.py +18 -22
  91. educommon/django/db/models.py +9 -8
  92. educommon/django/db/observer.py +9 -27
  93. educommon/django/db/partitioning/__init__.py +66 -92
  94. educommon/django/db/partitioning/management/commands/apply_partitioning.py +3 -13
  95. educommon/django/db/partitioning/management/commands/clear_table.py +18 -14
  96. educommon/django/db/partitioning/management/commands/split_table.py +18 -13
  97. educommon/django/db/routers.py +6 -15
  98. educommon/django/db/signals.py +149 -2
  99. educommon/django/db/utils.py +14 -19
  100. educommon/django/db/validators/__init__.py +1 -0
  101. educommon/django/db/validators/simple.py +72 -100
  102. educommon/django/storages/atcfs/api.py +39 -53
  103. educommon/django/storages/atcfs/app_meta.py +1 -1
  104. educommon/django/storages/atcfs/management/commands/atcfs_migrate.py +42 -55
  105. educommon/django/storages/atcfs/models.py +0 -3
  106. educommon/django/storages/atcfs/monkey_patching.py +18 -12
  107. educommon/django/storages/atcfs/storage.py +14 -23
  108. educommon/extjs/fields/input_params.py +15 -45
  109. educommon/importer/XLSReader.py +143 -241
  110. educommon/importer/__init__.py +86 -4
  111. educommon/importer/api.py +53 -84
  112. educommon/importer/constants.py +4 -14
  113. educommon/importer/loggers.py +16 -26
  114. educommon/importer/proxy.py +131 -176
  115. educommon/importer/proxy_import.py +11 -12
  116. educommon/importer/report.py +4 -6
  117. educommon/importer/ui.py +32 -26
  118. educommon/importer/validators.py +4 -7
  119. educommon/integration_entities/helpers.py +14 -18
  120. educommon/ioc/__init__.py +3 -6
  121. educommon/logger/loggers.py +10 -14
  122. educommon/m3/__init__.py +20 -38
  123. educommon/m3/extensions/__init__.py +1 -0
  124. educommon/m3/extensions/listeners/__init__.py +22 -38
  125. educommon/m3/extensions/listeners/delete_check/listeners.py +31 -41
  126. educommon/m3/extensions/listeners/delete_check/mixins.py +20 -25
  127. educommon/m3/extensions/listeners/delete_check/signals.py +2 -2
  128. educommon/m3/extensions/listeners/delete_check/ui.py +15 -14
  129. educommon/m3/extensions/listeners/delete_check/utils.py +9 -11
  130. educommon/m3/extensions/ui.py +15 -33
  131. educommon/m3/transaction_context.py +17 -19
  132. educommon/objectpack/actions.py +70 -88
  133. educommon/objectpack/apps.py +5 -0
  134. educommon/objectpack/filters.py +9 -15
  135. educommon/objectpack/ui.py +59 -77
  136. educommon/report/__init__.py +9 -5
  137. educommon/report/actions.py +29 -32
  138. educommon/report/constructor/__init__.py +5 -8
  139. educommon/report/constructor/app_meta.py +1 -3
  140. educommon/report/constructor/apps.py +1 -0
  141. educommon/report/constructor/base.py +33 -80
  142. educommon/report/constructor/builders/excel/_base.py +138 -286
  143. educommon/report/constructor/builders/excel/_header.py +2 -9
  144. educommon/report/constructor/builders/excel/product.py +13 -34
  145. educommon/report/constructor/builders/excel/with_merged_cells.py +18 -14
  146. educommon/report/constructor/config.py +2 -0
  147. educommon/report/constructor/editor/actions.py +101 -215
  148. educommon/report/constructor/editor/ui.py +71 -93
  149. educommon/report/constructor/exceptions.py +6 -12
  150. educommon/report/constructor/migrations/0001_initial.py +36 -44
  151. educommon/report/constructor/migrations/0002_report_filters.py +86 -72
  152. educommon/report/constructor/migrations/0003_reportfilter_exclude.py +5 -5
  153. educommon/report/constructor/migrations/0004_reportfilter_fields.py +22 -18
  154. educommon/report/constructor/migrations/0005_reportcolumn_visible.py +5 -4
  155. educommon/report/constructor/migrations/0006_reportsorting.py +21 -17
  156. educommon/report/constructor/migrations/0007_include_available_units.py +14 -14
  157. educommon/report/constructor/migrations/0008_auto_20170407_1318.py +4 -5
  158. educommon/report/constructor/migrations/0009_auto_20180405_0642.py +1 -4
  159. educommon/report/constructor/migrations/0010_add_aggregate_fields.py +7 -8
  160. educommon/report/constructor/mixins.py +14 -15
  161. educommon/report/constructor/models.py +76 -124
  162. educommon/report/constructor/utils.py +3 -8
  163. educommon/report/constructor/validators.py +1 -3
  164. educommon/report/reporter.py +25 -43
  165. educommon/report/utils.py +14 -40
  166. educommon/rest/actions.py +7 -11
  167. educommon/rest/context.py +6 -16
  168. educommon/rest/controllers.py +10 -10
  169. educommon/rest/mixins.py +29 -27
  170. educommon/secure_media/app_meta.py +9 -9
  171. educommon/utils/__init__.py +3 -2
  172. educommon/utils/caching.py +1 -3
  173. educommon/utils/conversion.py +1 -3
  174. educommon/utils/crypto.py +1 -2
  175. educommon/utils/date.py +13 -26
  176. educommon/utils/db/__init__.py +17 -26
  177. educommon/utils/db/postgresql.py +1 -4
  178. educommon/utils/fonts/__init__.py +3 -4
  179. educommon/utils/licence/__init__.py +5 -16
  180. educommon/utils/misc.py +9 -18
  181. educommon/utils/object_grid.py +55 -62
  182. educommon/utils/phone_number/modelfields.py +1 -3
  183. educommon/utils/phone_number/phone_number.py +5 -8
  184. educommon/utils/phone_number/validators.py +8 -23
  185. educommon/utils/plugins.py +15 -28
  186. educommon/utils/registry.py +2 -1
  187. educommon/utils/seqtools.py +1 -3
  188. educommon/utils/serializer.py +9 -16
  189. educommon/utils/storage.py +3 -2
  190. educommon/utils/system.py +1 -3
  191. educommon/utils/system_app/management/commands/delete_objects.py +17 -34
  192. educommon/utils/ui.py +87 -84
  193. educommon/utils/xml/__init__.py +2 -7
  194. educommon/utils/xml/resolver.py +1 -0
  195. educommon/ws_log/actions.py +31 -76
  196. educommon/ws_log/base.py +6 -20
  197. educommon/ws_log/migrations/0001_initial.py +25 -8
  198. educommon/ws_log/migrations/0002_auto_20160628_1334.py +0 -1
  199. educommon/ws_log/migrations/0003_add_fields_to_smev_logs.py +20 -4
  200. educommon/ws_log/migrations/0004_auto_20160727_1600.py +7 -6
  201. educommon/ws_log/migrations/0005_auto_20161130_1615.py +14 -4
  202. educommon/ws_log/migrations/0006_auto_20170327_1027.py +3 -2
  203. educommon/ws_log/migrations/0007_auto_20180607_1040.py +8 -9
  204. educommon/ws_log/migrations/0008_auto_20180713_1445.py +23 -10
  205. educommon/ws_log/migrations/0009_auto_20201130_1553.py +7 -2
  206. educommon/ws_log/models.py +21 -35
  207. educommon/ws_log/provider.py +2 -1
  208. educommon/ws_log/report.py +8 -13
  209. educommon/ws_log/smev/applications.py +12 -27
  210. educommon/ws_log/smev/exceptions.py +2 -3
  211. educommon/ws_log/ui.py +32 -32
  212. educommon/ws_log/utils.py +1 -3
  213. educommon-3.13.2.dist-info/METADATA +57 -0
  214. educommon-3.13.2.dist-info/RECORD +354 -0
  215. {educommon-3.12.0.dist-info → educommon-3.13.2.dist-info}/WHEEL +1 -1
  216. educommon/utils/patches.py +0 -27
  217. educommon/version.conf +0 -11
  218. educommon-3.12.0.dist-info/METADATA +0 -47
  219. educommon-3.12.0.dist-info/RECORD +0 -357
  220. educommon-3.12.0.dist-info/dependency_links.txt +0 -1
  221. {educommon-3.12.0.dist-info → educommon-3.13.2.dist-info}/top_level.txt +0 -0
@@ -79,42 +79,24 @@ class AuditLogPack(ViewWindowPackMixin, PackValidationMixin, ObjectPack):
79
79
 
80
80
  # Фильтр интервала дат
81
81
  date_filter = DatetimeFilterCreator(
82
- model, 'time',
83
- get_from=lambda: date.today() - timedelta(days=2),
84
- get_to=date.today
82
+ model, 'time', get_from=lambda: date.today() - timedelta(days=2), get_to=date.today
85
83
  )
86
84
 
87
85
  columns = [
88
- {
89
- 'data_index': 'time',
90
- 'width': 140,
91
- 'header': 'Дата и время',
92
- 'sortable': True,
93
- 'filter': date_filter.filter
94
- },
86
+ {'data_index': 'time', 'width': 140, 'header': 'Дата и время', 'sortable': True, 'filter': date_filter.filter},
95
87
  {
96
88
  'data_index': 'user_name',
97
89
  'width': 130,
98
90
  'header': 'Пользователь',
99
- 'filter': ff(
100
- 'table__name',
101
- lookup=lambda x: make_name_filter('surname', x)
102
- ) & ff(
103
- 'table__name',
104
- lookup=lambda x: make_name_filter('firstname', x)
105
- ) & ff(
106
- 'table__name',
107
- lookup=lambda x: make_name_filter('patronymic', x)
108
- )
91
+ 'filter': ff('table__name', lookup=lambda x: make_name_filter('surname', x))
92
+ & ff('table__name', lookup=lambda x: make_name_filter('firstname', x))
93
+ & ff('table__name', lookup=lambda x: make_name_filter('patronymic', x)),
109
94
  },
110
95
  {
111
96
  'data_index': 'operation',
112
97
  'width': 60,
113
98
  'header': 'Операция',
114
- 'filter': ff(
115
- 'operation',
116
- ask_before_deleting=False
117
- ),
99
+ 'filter': ff('operation', ask_before_deleting=False),
118
100
  },
119
101
  {
120
102
  'data_index': 'model_name',
@@ -158,7 +140,8 @@ class AuditLogPack(ViewWindowPackMixin, PackValidationMixin, ObjectPack):
158
140
  ]
159
141
 
160
142
  def __init__(self):
161
- super(AuditLogPack, self).__init__()
143
+ super().__init__()
144
+
162
145
  self.view_changes_action = ViewChangeAction()
163
146
  self.actions.append(self.view_changes_action)
164
147
 
@@ -174,29 +157,32 @@ class AuditLogPack(ViewWindowPackMixin, PackValidationMixin, ObjectPack):
174
157
  Устанавливает интервал дат фильтрации по умолчанию
175
158
  в параметрах запроса.
176
159
  """
177
- super(AuditLogPack, self).configure_grid(grid)
160
+ super().configure_grid(grid)
161
+
178
162
  grid.store.base_params = self.date_filter.base_params
179
163
 
180
164
  def get_edit_window_params(self, params, request, context):
181
- params = super(AuditLogPack, self).get_edit_window_params(
182
- params, request, context
183
- )
165
+ """Возвращает словарь параметров, которые будут переданы окну редактирования."""
166
+ params = super().get_edit_window_params(params, request, context)
167
+
184
168
  params['grid_action'] = self.view_changes_action
169
+
185
170
  return params
186
171
 
187
172
  def get_list_window_params(self, params, request, context):
188
- params = super(AuditLogPack, self).get_list_window_params(
189
- params, request, context
190
- )
173
+ """Возвращает словарь параметров, которые будут переданы окну списка."""
174
+ params = super().get_list_window_params(params, request, context)
175
+
191
176
  params['maximized'] = True
177
+
192
178
  return params
193
179
 
194
180
  def get_rows_query(self, request, context):
195
- return super(AuditLogPack, self).get_rows_query(
196
- request, context
197
- ).prefetch_related('table')
181
+ """Возвращает выборку из БД для получения списка данных."""
182
+ return super().get_rows_query(request, context).prefetch_related('table')
198
183
 
199
184
  def extend_menu(self, menu):
185
+ """Расширение главного меню."""
200
186
  return menu.administry(
201
187
  menu.Item(self.title, self.list_window_action),
202
188
  )
@@ -206,14 +192,19 @@ class ViewChangeAction(BaseAction):
206
192
  """Action для просмотра изменений."""
207
193
 
208
194
  def context_declaration(self):
209
- result = super(ViewChangeAction, self).context_declaration()
195
+ """Делегирует декларацию контекста в пак."""
196
+ result = super().context_declaration()
197
+
210
198
  result[self.parent.id_param_name] = dict(type='int')
199
+
211
200
  return result
212
201
 
213
202
  def run(self, request, context):
203
+ """Тело Action, вызывается при обработке запроса к серверу."""
214
204
  object_id = getattr(context, self.parent.id_param_name)
215
205
  if object_id:
216
206
  rows = LogProxy.objects.get(id=object_id).diff
217
207
  else:
218
208
  rows = []
209
+
219
210
  return PreJsonResult({'rows': rows, 'total': len(rows)})
@@ -10,7 +10,10 @@ from educommon.audit_log.error_log.actions import (
10
10
 
11
11
 
12
12
  def register_actions():
13
- ioc.get('main_controller').packs.extend((
14
- AuditLogPack(),
15
- PostgreSQLErrorPack(),
16
- ))
13
+ """Регистрация паков и экшенов."""
14
+ ioc.get('main_controller').packs.extend(
15
+ (
16
+ AuditLogPack(),
17
+ PostgreSQLErrorPack(),
18
+ )
19
+ )
@@ -30,16 +30,30 @@ from educommon.utils.db.postgresql import (
30
30
 
31
31
 
32
32
  class AppConfig(AppConfig):
33
+ """Конфигурация подсистемы логирования изменений в БД.
34
+
35
+ При инициализации приложения:
36
+ - подключает обработку сигнала post_migrate;
37
+ - создаёт необходимые расширения PostgreSQL (hstore, postgres_fdw);
38
+ - проверяет и настраивает подключение к сервисной БД через FDW;
39
+ - выполняет установку и проверку инфраструктуры AuditLog.
40
+ """
33
41
 
34
42
  name = __name__.rpartition('.')[0]
35
43
 
36
44
  @property
37
45
  def _dispatch_uid(self):
38
- return '.'.join((
39
- self.name,
40
- self.__class__.__name__,
41
- self._configure_audit_log.__name__,
42
- ))
46
+ """Уникальный идентификатор для подключения сигнала post_migrate.
47
+
48
+ Используется для предотвращения дублирующего подключения обработчиков.
49
+ """
50
+ return '.'.join(
51
+ (
52
+ self.name,
53
+ self.__class__.__name__,
54
+ self._configure_audit_log.__name__,
55
+ )
56
+ )
43
57
 
44
58
  def _create_postgresql_extensions(self):
45
59
  """Создает в БД необходимые расширения PostgreSQL.
@@ -52,13 +66,9 @@ class AppConfig(AppConfig):
52
66
  if not is_extension_exists(alias, 'postgres_fdw'):
53
67
  if create_extension(alias, 'postgres_fdw', quite=True):
54
68
  with closing(connections[alias].cursor()) as cursor:
55
- cursor.execute(
56
- 'GRANT USAGE ON FOREIGN DATA WRAPPER postgres_fdw '
57
- 'TO PUBLIC'
58
- )
69
+ cursor.execute('GRANT USAGE ON FOREIGN DATA WRAPPER postgres_fdw TO PUBLIC')
59
70
 
60
- for alias in (settings.DEFAULT_DB_ALIAS,
61
- settings.SERVICE_DB_ALIAS):
71
+ for alias in (settings.DEFAULT_DB_ALIAS, settings.SERVICE_DB_ALIAS):
62
72
  if not is_extension_exists(alias, 'hstore'):
63
73
  create_extension(alias, 'hstore', quite=True)
64
74
 
@@ -68,32 +78,41 @@ class AppConfig(AppConfig):
68
78
  from educommon.audit_log.utils import (
69
79
  configure,
70
80
  )
81
+
71
82
  configure()
72
83
 
73
84
  # Проверка подключения подключения к сервисной БД через FDW.
74
85
  from educommon.audit_log.utils import (
75
86
  check_connection_fdw,
76
87
  )
88
+
77
89
  success, error_message = check_connection_fdw()
78
90
  if not success:
79
91
  raise ImproperlyConfigured(
80
- "{0} - Ошибка подключения к сервисной базе через "
92
+ '{0} - Ошибка подключения к сервисной базе через '
81
93
  "postgres_fdw. Необходимо убедится что 'Журнал изменений' "
82
- "настроен корректно.".format(error_message)
94
+ 'настроен корректно.'.format(error_message)
83
95
  )
84
96
 
85
97
  def _configure_db(self, **kwargs):
98
+ """Инициализирует расширения PostgreSQL и настраивает AuditLog.
99
+
100
+ Вызывается после применения миграций. Если AuditLog уже инициализирован,
101
+ выполняется его настройка.
102
+ """
86
103
  from educommon.audit_log.utils import (
87
104
  is_initialized,
88
105
  )
89
106
 
90
107
  self._create_postgresql_extensions()
91
108
  if is_initialized(settings.DEFAULT_DB_ALIAS):
92
- self._configure_audit_log(
93
- connections[settings.DEFAULT_DB_ALIAS]
94
- )
109
+ self._configure_audit_log(connections[settings.DEFAULT_DB_ALIAS])
95
110
 
96
111
  def ready(self):
112
+ """Вызывается при готовности приложения.
113
+
114
+ Подключает обработчик _configure_db к сигналу post_migrate.
115
+ """
97
116
  post_migrate.connect(self._configure_db, sender=self)
98
117
 
99
118
 
@@ -104,10 +123,7 @@ def check_postgres_fdw(app_configs, **kwargs):
104
123
 
105
124
  if not is_extension_exists(settings.DEFAULT_DB_ALIAS, 'postgres_fdw'):
106
125
  dbname = settings.DATABASES[settings.DEFAULT_DB_ALIAS]['NAME']
107
- msg = (
108
- "'postgres_fdw' PostgreSQL extension not installed in '{}' "
109
- "database."
110
- ).format(dbname)
126
+ msg = ("'postgres_fdw' PostgreSQL extension not installed in '{}' database.").format(dbname)
111
127
  hint = (
112
128
  "Execute this SQL in '{dbname}' database:\n"
113
129
  '{indent}CREATE EXTENSION postgres_fdw;\n'
@@ -125,20 +141,19 @@ def check_hstore(app_configs, **kwargs):
125
141
  errors = []
126
142
 
127
143
  msg = "'hstore' PostgreSQL extension not installed in '{}' database."
128
- hint = (
129
- "Execute this SQL in '{dbname}' database:\n"
130
- '{indent}CREATE EXTENSION hstore;'
131
- )
144
+ hint = "Execute this SQL in '{dbname}' database:\n{indent}CREATE EXTENSION hstore;"
132
145
  indent = ' ' * 14
133
146
 
134
147
  def check(alias, message_id):
135
148
  dbname = settings.DATABASES[alias]['NAME']
136
149
  if not is_extension_exists(alias, 'hstore'):
137
- errors.append(Critical(
138
- msg.format(dbname),
139
- hint.format(indent=indent, dbname=dbname),
140
- id=message_id,
141
- ))
150
+ errors.append(
151
+ Critical(
152
+ msg.format(dbname),
153
+ hint.format(indent=indent, dbname=dbname),
154
+ id=message_id,
155
+ )
156
+ )
142
157
 
143
158
  check(settings.DEFAULT_DB_ALIAS, 'audit_log.C002')
144
159
  check(settings.SERVICE_DB_ALIAS, 'audit_log.C003')
@@ -21,8 +21,11 @@ EXCLUDED_TABLES = (
21
21
  )
22
22
 
23
23
  # Папка с sql файлами
24
- SQL_FILES_DIR = os.path.abspath(os.path.join(
25
- os.path.dirname(__file__), 'sql',
26
- ))
24
+ SQL_FILES_DIR = os.path.abspath(
25
+ os.path.join(
26
+ os.path.dirname(__file__),
27
+ 'sql',
28
+ )
29
+ )
27
30
 
28
- INSTALL_AUDIT_LOG_SQL_FILE_NAME = 'install_audit_log.sql'
31
+ INSTALL_AUDIT_LOG_SQL_FILE_NAME = 'install_audit_log.sql'
@@ -72,9 +72,7 @@ class PostgreSQLErrorPack(PackValidationMixin, ObjectPack):
72
72
  )
73
73
 
74
74
  def get_list_window_params(self, params, request, context):
75
- result = super(PostgreSQLErrorPack, self).get_list_window_params(
76
- params, request, context
77
- )
75
+ result = super(PostgreSQLErrorPack, self).get_list_window_params(params, request, context)
78
76
 
79
77
  result['maximized'] = True
80
78
  result['read_only'] = not self.delete_action.has_perm(request)
@@ -20,11 +20,9 @@ if TYPE_CHECKING:
20
20
 
21
21
 
22
22
  def get_models_table_ids(models: Union['Model', IterableType['Model']]) -> List[int]:
23
- """
24
- Возвращает перечень id таблиц из AuditLog соответствующих указанным моделям.
25
- """
23
+ """Возвращает перечень id таблиц из AuditLog соответствующих указанным моделям."""
26
24
  if not isinstance(models, Iterable):
27
- models = (models, )
25
+ models = (models,)
28
26
 
29
27
  table_ids = Table.objects.filter(
30
28
  name__in=(model._meta.db_table for model in models),
@@ -37,14 +37,18 @@ class Command(BaseCommand):
37
37
 
38
38
  def add_arguments(self, parser):
39
39
  """Добавление аргументов команды."""
40
+ (
41
+ parser.add_argument(
42
+ '--clear_audit_logs',
43
+ action='store_true',
44
+ default=False,
45
+ help='Удалить записи из audit_log для неотслеживаемых таблиц',
46
+ ),
47
+ )
40
48
  parser.add_argument(
41
- '--clear_audit_logs',
42
- action='store_true',
43
- default=False,
44
- help='Удалить записи из audit_log для неотслеживаемых таблиц',
45
- ),
46
- parser.add_argument(
47
- '--chunk_size', type=int, default=DEFAULT_QUERYSET_CHUNK_SIZE,
49
+ '--chunk_size',
50
+ type=int,
51
+ default=DEFAULT_QUERYSET_CHUNK_SIZE,
48
52
  help='Кол-во единовременно удаляемых записей',
49
53
  )
50
54
 
@@ -12,9 +12,7 @@ from educommon.django.db.migration.operations import (
12
12
 
13
13
 
14
14
  class Migration(migrations.Migration):
15
-
16
- dependencies = [
17
- ]
15
+ dependencies = []
18
16
 
19
17
  operations = [
20
18
  CreateSchema('audit', aliases=('default',)),
@@ -22,11 +20,33 @@ class Migration(migrations.Migration):
22
20
  name='PostgreSQLError',
23
21
  fields=[
24
22
  ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
25
- ('user_id', models.IntegerField(null=True, verbose_name='\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c')),
23
+ (
24
+ 'user_id',
25
+ models.IntegerField(
26
+ null=True,
27
+ verbose_name='\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c',
28
+ ),
29
+ ),
26
30
  ('ip', models.GenericIPAddressField(null=True, verbose_name='IP \u0430\u0434\u0440\u0435\u0441')),
27
- ('time', models.DateTimeField(auto_now_add=True, verbose_name='\u0414\u0430\u0442\u0430, \u0432\u0440\u0435\u043c\u044f')),
28
- ('level', models.CharField(max_length=50, verbose_name='\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u0448\u0438\u0431\u043a\u0438')),
29
- ('text', models.TextField(verbose_name='\u0422\u0435\u043a\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0438')),
31
+ (
32
+ 'time',
33
+ models.DateTimeField(
34
+ auto_now_add=True, verbose_name='\u0414\u0430\u0442\u0430, \u0432\u0440\u0435\u043c\u044f'
35
+ ),
36
+ ),
37
+ (
38
+ 'level',
39
+ models.CharField(
40
+ max_length=50,
41
+ verbose_name='\u0423\u0440\u043e\u0432\u0435\u043d\u044c \u043e\u0448\u0438\u0431\u043a\u0438',
42
+ ),
43
+ ),
44
+ (
45
+ 'text',
46
+ models.TextField(
47
+ verbose_name='\u0422\u0435\u043a\u0441\u0442 \u043e\u0448\u0438\u0431\u043a\u0438'
48
+ ),
49
+ ),
30
50
  ],
31
51
  options={
32
52
  'db_table': 'audit"."postgresql_errors',
@@ -38,14 +58,54 @@ class Migration(migrations.Migration):
38
58
  name='AuditLog',
39
59
  fields=[
40
60
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
41
- ('user_id', models.IntegerField(null=True, verbose_name='\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c', db_index=True)),
42
- ('user_type_id', models.IntegerField(null=True, verbose_name='\u0422\u0438\u043f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f', db_index=True)),
61
+ (
62
+ 'user_id',
63
+ models.IntegerField(
64
+ null=True,
65
+ verbose_name='\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c',
66
+ db_index=True,
67
+ ),
68
+ ),
69
+ (
70
+ 'user_type_id',
71
+ models.IntegerField(
72
+ null=True,
73
+ verbose_name='\u0422\u0438\u043f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f',
74
+ db_index=True,
75
+ ),
76
+ ),
43
77
  ('ip', models.GenericIPAddressField(null=True, verbose_name='IP \u0430\u0434\u0440\u0435\u0441')),
44
- ('time', models.DateTimeField(auto_now_add=True, verbose_name='\u0414\u0430\u0442\u0430, \u0432\u0440\u0435\u043c\u044f', db_index=True)),
45
- ('object_id', models.IntegerField(verbose_name='\u041e\u0431\u044a\u0435\u043a\u0442 \u043c\u043e\u0434\u0435\u043b\u0438', db_index=True)),
78
+ (
79
+ 'time',
80
+ models.DateTimeField(
81
+ auto_now_add=True,
82
+ verbose_name='\u0414\u0430\u0442\u0430, \u0432\u0440\u0435\u043c\u044f',
83
+ db_index=True,
84
+ ),
85
+ ),
86
+ (
87
+ 'object_id',
88
+ models.IntegerField(
89
+ verbose_name='\u041e\u0431\u044a\u0435\u043a\u0442 \u043c\u043e\u0434\u0435\u043b\u0438',
90
+ db_index=True,
91
+ ),
92
+ ),
46
93
  ('data', HStoreField(null=True, verbose_name='\u041e\u0431\u044a\u0435\u043a\u0442')),
47
- ('changes', HStoreField(null=True, verbose_name='\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f')),
48
- ('operation', models.SmallIntegerField(verbose_name='\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435', choices=[(1, '\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435'), (2, '\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435'), (3, '\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435')])),
94
+ (
95
+ 'changes',
96
+ HStoreField(null=True, verbose_name='\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f'),
97
+ ),
98
+ (
99
+ 'operation',
100
+ models.SmallIntegerField(
101
+ verbose_name='\u0414\u0435\u0439\u0441\u0442\u0432\u0438\u0435',
102
+ choices=[
103
+ (1, '\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435'),
104
+ (2, '\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435'),
105
+ (3, '\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435'),
106
+ ],
107
+ ),
108
+ ),
49
109
  ],
50
110
  options={
51
111
  'abstract': False,
@@ -56,8 +116,19 @@ class Migration(migrations.Migration):
56
116
  name='Table',
57
117
  fields=[
58
118
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
59
- ('name', models.CharField(max_length=250, verbose_name='\u0418\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b')),
60
- ('schema', models.CharField(max_length=250, verbose_name='\u0421\u0445\u0435\u043c\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b')),
119
+ (
120
+ 'name',
121
+ models.CharField(
122
+ max_length=250, verbose_name='\u0418\u043c\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u044b'
123
+ ),
124
+ ),
125
+ (
126
+ 'schema',
127
+ models.CharField(
128
+ max_length=250,
129
+ verbose_name='\u0421\u0445\u0435\u043c\u0430 \u0442\u0430\u0431\u043b\u0438\u0446\u044b',
130
+ ),
131
+ ),
61
132
  ],
62
133
  options={
63
134
  'verbose_name': '\u041b\u043e\u0433\u0438\u0440\u0443\u0435\u043c\u0430\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430',
@@ -72,7 +143,11 @@ class Migration(migrations.Migration):
72
143
  migrations.AddField(
73
144
  model_name='auditlog',
74
145
  name='table',
75
- field=models.ForeignKey(verbose_name='\u0422\u0430\u0431\u043b\u0438\u0446\u0430', to='audit_log.Table', on_delete=models.CASCADE),
146
+ field=models.ForeignKey(
147
+ verbose_name='\u0422\u0430\u0431\u043b\u0438\u0446\u0430',
148
+ to='audit_log.Table',
149
+ on_delete=models.CASCADE,
150
+ ),
76
151
  preserve_default=True,
77
152
  ),
78
153
  ]
@@ -30,8 +30,7 @@ class InitDefaultDatabase(Operation):
30
30
  def state_forwards(self, app_label, state):
31
31
  pass
32
32
 
33
- def database_forwards(self, app_label, schema_editor, from_state,
34
- to_state):
33
+ def database_forwards(self, app_label, schema_editor, from_state, to_state):
35
34
  if schema_editor.connection.alias != settings.DEFAULT_DB_ALIAS:
36
35
  return
37
36
 
@@ -44,8 +43,7 @@ class InitDefaultDatabase(Operation):
44
43
 
45
44
  schema_editor.execute(sql)
46
45
 
47
- def database_backwards(self, app_label, schema_editor, from_state,
48
- to_state):
46
+ def database_backwards(self, app_label, schema_editor, from_state, to_state):
49
47
  if schema_editor.connection.alias != settings.DEFAULT_DB_ALIAS:
50
48
  return
51
49
 
@@ -64,24 +62,26 @@ class LoadTableData(Operation):
64
62
  def state_forwards(self, app_label, state):
65
63
  pass
66
64
 
67
- def database_forwards(self, app_label, schema_editor, from_state,
68
- to_state):
65
+ def database_forwards(self, app_label, schema_editor, from_state, to_state):
69
66
  Table = to_state.apps.get_model('audit_log', 'Table')
70
67
 
71
68
  if self.allow_migrate_model(schema_editor.connection.alias, Table):
72
69
  cursor = connections[settings.DEFAULT_DB_ALIAS].cursor()
73
- cursor.execute('\n'.join((
74
- "SELECT table_name, table_schema",
75
- "FROM information_schema.tables",
76
- "WHERE table_schema = 'public'",
77
- )))
70
+ cursor.execute(
71
+ '\n'.join(
72
+ (
73
+ 'SELECT table_name, table_schema',
74
+ 'FROM information_schema.tables',
75
+ "WHERE table_schema = 'public'",
76
+ )
77
+ )
78
+ )
78
79
 
79
80
  for name, schema in cursor:
80
81
  if (schema, name) not in EXCLUDED_TABLES:
81
82
  Table.objects.get_or_create(name=name, schema=schema)
82
83
 
83
- def database_backwards(self, app_label, schema_editor, from_state,
84
- to_state):
84
+ def database_backwards(self, app_label, schema_editor, from_state, to_state):
85
85
  pass
86
86
 
87
87
 
@@ -4,7 +4,6 @@ from django.db import (
4
4
 
5
5
 
6
6
  class Migration(migrations.Migration):
7
-
8
7
  dependencies = [
9
8
  ('audit_log', '0002_install_audit_log'),
10
9
  ]
@@ -12,8 +11,7 @@ class Migration(migrations.Migration):
12
11
  operations = [
13
12
  migrations.CreateModel(
14
13
  name='LogProxy',
15
- fields=[
16
- ],
14
+ fields=[],
17
15
  options={
18
16
  'proxy': True,
19
17
  },
@@ -8,11 +8,8 @@ from educommon.audit_log.utils.operations import (
8
8
 
9
9
 
10
10
  class Migration(migrations.Migration):
11
-
12
11
  dependencies = [
13
12
  ('audit_log', '0003_logproxy'),
14
13
  ]
15
14
 
16
- operations = [
17
- ReinstallAuditLog()
18
- ]
15
+ operations = [ReinstallAuditLog()]
@@ -8,7 +8,6 @@ from educommon.audit_log.utils.operations import (
8
8
 
9
9
 
10
10
  class Migration(migrations.Migration):
11
-
12
11
  dependencies = [
13
12
  ('audit_log', '0004_reinstall_audit_log'),
14
13
  ]
@@ -17,6 +16,9 @@ class Migration(migrations.Migration):
17
16
  ReinstallAuditLog(),
18
17
  migrations.AlterModelOptions(
19
18
  name='auditlog',
20
- options={'verbose_name': '\u0417\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439', 'verbose_name_plural': '\u0417\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439'},
19
+ options={
20
+ 'verbose_name': '\u0417\u0430\u043f\u0438\u0441\u044c \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439',
21
+ 'verbose_name_plural': '\u0417\u0430\u043f\u0438\u0441\u0438 \u0436\u0443\u0440\u043d\u0430\u043b\u0430 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439',
22
+ },
21
23
  ),
22
24
  ]
@@ -8,7 +8,6 @@ from django.db import (
8
8
 
9
9
 
10
10
  class Migration(migrations.Migration):
11
-
12
11
  dependencies = [
13
12
  ('audit_log', '0005_postgresql_error'),
14
13
  ]
@@ -19,8 +18,8 @@ class Migration(migrations.Migration):
19
18
  name='time',
20
19
  field=models.DateTimeField(
21
20
  auto_now_add=True,
22
- validators=[django.core.validators.MinValueValidator(
23
- datetime.datetime(1900, 1, 1, 0, 0))],
24
- verbose_name='Дата, время'),
21
+ validators=[django.core.validators.MinValueValidator(datetime.datetime(1900, 1, 1, 0, 0))],
22
+ verbose_name='Дата, время',
23
+ ),
25
24
  ),
26
25
  ]
@@ -13,14 +13,17 @@ def drop_select_table_function(apps, schema_editor):
13
13
  return
14
14
 
15
15
  cursor = connections[settings.DEFAULT_DB_ALIAS].cursor()
16
- cursor.execute('\n'.join((
17
- "SELECT",
18
- "audit.drop_functions_by_name('set_for_selective_tables_triggers');",
19
- )))
16
+ cursor.execute(
17
+ '\n'.join(
18
+ (
19
+ 'SELECT',
20
+ "audit.drop_functions_by_name('set_for_selective_tables_triggers');",
21
+ )
22
+ )
23
+ )
20
24
 
21
25
 
22
26
  class Migration(migrations.Migration):
23
-
24
27
  dependencies = [
25
28
  ('audit_log', '0006_auto_20200806_1707'),
26
29
  ]
@@ -7,7 +7,6 @@ from django.db import (
7
7
 
8
8
 
9
9
  class Migration(migrations.Migration):
10
-
11
10
  dependencies = [
12
11
  ('audit_log', '0007_create_selective_tables_function'),
13
12
  ]