django-cfg 1.4.106__py3-none-any.whl → 1.4.108__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 django-cfg might be problematic. Click here for more details.
- django_cfg/__init__.py +1 -1
- django_cfg/apps/accounts/views/profile.py +19 -9
- django_cfg/apps/centrifugo/views/admin_api.py +4 -7
- django_cfg/apps/centrifugo/views/monitoring.py +3 -6
- django_cfg/apps/centrifugo/views/testing_api.py +3 -6
- django_cfg/apps/dashboard/services/system_health_service.py +16 -11
- django_cfg/apps/dashboard/views/activity_views.py +3 -5
- django_cfg/apps/dashboard/views/apizones_views.py +4 -5
- django_cfg/apps/dashboard/views/charts_views.py +4 -5
- django_cfg/apps/dashboard/views/overview_views.py +4 -5
- django_cfg/apps/dashboard/views/statistics_views.py +4 -5
- django_cfg/apps/dashboard/views/system_views.py +4 -5
- django_cfg/apps/knowbase/__init__.py +2 -2
- django_cfg/apps/knowbase/apps.py +2 -8
- django_cfg/apps/knowbase/views/base.py +9 -4
- django_cfg/apps/support/views/api.py +16 -7
- django_cfg/apps/tasks/__init__.py +61 -2
- django_cfg/apps/tasks/admin/__init__.py +3 -10
- django_cfg/apps/tasks/admin/config.py +98 -0
- django_cfg/apps/tasks/admin/task_log.py +265 -0
- django_cfg/apps/tasks/apps.py +7 -9
- django_cfg/apps/tasks/filters/__init__.py +10 -0
- django_cfg/apps/tasks/filters/task_log.py +121 -0
- django_cfg/apps/tasks/migrations/0001_initial.py +196 -0
- django_cfg/apps/tasks/models/__init__.py +4 -0
- django_cfg/apps/tasks/models/task_log.py +246 -0
- django_cfg/apps/tasks/serializers/__init__.py +28 -0
- django_cfg/apps/tasks/serializers/task_log.py +249 -0
- django_cfg/apps/tasks/services/__init__.py +10 -0
- django_cfg/apps/tasks/services/client/__init__.py +7 -0
- django_cfg/apps/tasks/services/client/client.py +234 -0
- django_cfg/apps/tasks/services/config_helper.py +63 -0
- django_cfg/apps/tasks/services/sync.py +204 -0
- django_cfg/apps/tasks/urls.py +7 -13
- django_cfg/apps/tasks/views/__init__.py +4 -10
- django_cfg/apps/tasks/views/task_log.py +41 -0
- django_cfg/apps/tasks/views/task_log_base.py +41 -0
- django_cfg/apps/tasks/views/task_log_overview.py +100 -0
- django_cfg/apps/tasks/views/task_log_related.py +41 -0
- django_cfg/apps/tasks/views/task_log_stats.py +91 -0
- django_cfg/apps/tasks/views/task_log_timeline.py +81 -0
- django_cfg/apps/urls.py +0 -1
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/cli/utils.py +1 -1
- django_cfg/core/base/config_model.py +1 -1
- django_cfg/core/builders/apps_builder.py +1 -1
- django_cfg/core/generation/integration_generators/__init__.py +1 -1
- django_cfg/core/generation/integration_generators/tasks.py +14 -18
- django_cfg/core/generation/security_generators/crypto_fields.py +2 -1
- django_cfg/core/integration/display/startup.py +1 -1
- django_cfg/mixins/__init__.py +12 -0
- django_cfg/mixins/admin_api.py +37 -0
- django_cfg/mixins/client_api.py +39 -0
- django_cfg/models/django/constance.py +2 -8
- django_cfg/models/django/crypto_fields.py +13 -48
- django_cfg/models/tasks/__init__.py +8 -10
- django_cfg/models/tasks/backends.py +76 -207
- django_cfg/models/tasks/config.py +20 -127
- django_cfg/models/tasks/utils.py +17 -29
- django_cfg/modules/django_admin/RESOURCE_CONFIG_ENHANCEMENT.md +350 -0
- django_cfg/modules/django_admin/__init__.py +4 -0
- django_cfg/modules/django_admin/base/pydantic_admin.py +70 -15
- django_cfg/modules/django_admin/config/__init__.py +4 -0
- django_cfg/modules/django_admin/config/admin_config.py +13 -1
- django_cfg/modules/django_admin/config/background_task_config.py +76 -0
- django_cfg/modules/django_admin/config/resource_config.py +129 -0
- django_cfg/modules/django_client/management/commands/generate_client.py +13 -1
- django_cfg/modules/django_unfold/navigation.py +121 -22
- django_cfg/pyproject.toml +2 -2
- django_cfg/registry/core.py +1 -1
- django_cfg/static/frontend/admin.zip +0 -0
- {django_cfg-1.4.106.dist-info → django_cfg-1.4.108.dist-info}/METADATA +5 -3
- {django_cfg-1.4.106.dist-info → django_cfg-1.4.108.dist-info}/RECORD +77 -111
- django_cfg/apps/tasks/admin/actions.py +0 -29
- django_cfg/apps/tasks/admin/tasks_admin.py +0 -154
- django_cfg/apps/tasks/api/serializers.py +0 -82
- django_cfg/apps/tasks/api/views.py +0 -571
- django_cfg/apps/tasks/serializers.py +0 -82
- django_cfg/apps/tasks/static/tasks/css/dashboard-alpine.css +0 -299
- django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -120
- django_cfg/apps/tasks/static/tasks/js/alpine/README.md +0 -47
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/index.js +0 -8
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/management.js +0 -123
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/pagination.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/tasks.js +0 -101
- django_cfg/apps/tasks/static/tasks/js/alpine/actions/workers.js +0 -59
- django_cfg/apps/tasks/static/tasks/js/alpine/computed.js +0 -35
- django_cfg/apps/tasks/static/tasks/js/alpine/index.js +0 -148
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/index.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/overview.js +0 -37
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/queues.js +0 -27
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/tasks.js +0 -32
- django_cfg/apps/tasks/static/tasks/js/alpine/loaders/workers.js +0 -21
- django_cfg/apps/tasks/static/tasks/js/alpine/state.js +0 -36
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/formatters.js +0 -42
- django_cfg/apps/tasks/static/tasks/js/alpine/utils/helpers.js +0 -68
- django_cfg/apps/tasks/static/tasks/js/dashboard-alpine.js +0 -725
- django_cfg/apps/tasks/tasks/__init__.py +0 -10
- django_cfg/apps/tasks/tasks/demo_tasks.py +0 -127
- django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -71
- django_cfg/apps/tasks/templates/tasks/components/overview_content.html +0 -94
- django_cfg/apps/tasks/templates/tasks/components/queues_content.html +0 -44
- django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -45
- django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -151
- django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +0 -61
- django_cfg/apps/tasks/templates/tasks/components/tasks_mjs_integration.html +0 -269
- django_cfg/apps/tasks/templates/tasks/components/workers_content.html +0 -60
- django_cfg/apps/tasks/templates/tasks/layout/base.html +0 -20
- django_cfg/apps/tasks/templates/tasks/pages/dashboard-improved.html +0 -168
- django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +0 -77
- django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +0 -40
- django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +0 -86
- django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +0 -90
- django_cfg/apps/tasks/urls_admin.py +0 -15
- django_cfg/apps/tasks/utils/__init__.py +0 -1
- django_cfg/apps/tasks/utils/simulator.py +0 -353
- django_cfg/apps/tasks/views/api.py +0 -571
- django_cfg/apps/tasks/views/dashboard.py +0 -89
- django_cfg/management/commands/rundramatiq.py +0 -24
- django_cfg/management/commands/rundramatiq_simulator.py +0 -22
- django_cfg/management/commands/task_clear.py +0 -25
- django_cfg/management/commands/task_status.py +0 -24
- django_cfg/modules/django_tasks/__init__.py +0 -29
- django_cfg/modules/django_tasks/dramatiq_setup.py +0 -20
- django_cfg/modules/django_tasks/factory.py +0 -127
- django_cfg/modules/django_tasks/management/commands/__init__.py +0 -0
- django_cfg/modules/django_tasks/management/commands/rundramatiq.py +0 -253
- django_cfg/modules/django_tasks/management/commands/rundramatiq_simulator.py +0 -436
- django_cfg/modules/django_tasks/management/commands/task_clear.py +0 -226
- django_cfg/modules/django_tasks/management/commands/task_status.py +0 -257
- django_cfg/modules/django_tasks/service.py +0 -281
- django_cfg/modules/django_tasks/settings.py +0 -107
- /django_cfg/{modules/django_tasks/management → apps/tasks/migrations}/__init__.py +0 -0
- {django_cfg-1.4.106.dist-info → django_cfg-1.4.108.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.106.dist-info → django_cfg-1.4.108.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.106.dist-info → django_cfg-1.4.108.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Resource configuration for import/export functionality.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
6
|
+
|
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class ResourceConfig(BaseModel):
|
|
11
|
+
"""
|
|
12
|
+
Configuration for django-import-export Resource class.
|
|
13
|
+
|
|
14
|
+
Provides declarative configuration for import/export behavior without
|
|
15
|
+
needing to manually create Resource classes.
|
|
16
|
+
|
|
17
|
+
Example:
|
|
18
|
+
```python
|
|
19
|
+
resource_config = ResourceConfig(
|
|
20
|
+
fields=['host', 'port', 'username', 'password', 'provider'],
|
|
21
|
+
exclude=['metadata', 'config'],
|
|
22
|
+
import_id_fields=['host', 'port'],
|
|
23
|
+
after_import_row='apps.proxies.services.test_proxy_async',
|
|
24
|
+
skip_unchanged=True,
|
|
25
|
+
)
|
|
26
|
+
```
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
model_config = ConfigDict(
|
|
30
|
+
validate_assignment=True,
|
|
31
|
+
extra="forbid",
|
|
32
|
+
arbitrary_types_allowed=True
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
# Field configuration
|
|
36
|
+
fields: List[str] = Field(
|
|
37
|
+
default_factory=list,
|
|
38
|
+
description="Fields to include in import/export (empty = all fields)"
|
|
39
|
+
)
|
|
40
|
+
exclude: List[str] = Field(
|
|
41
|
+
default_factory=list,
|
|
42
|
+
description="Fields to exclude from import/export"
|
|
43
|
+
)
|
|
44
|
+
import_id_fields: List[str] = Field(
|
|
45
|
+
default_factory=lambda: ['id'],
|
|
46
|
+
description="Fields used to identify existing rows during import"
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
# Import behavior
|
|
50
|
+
skip_unchanged: bool = Field(
|
|
51
|
+
True,
|
|
52
|
+
description="Skip rows that haven't changed during import"
|
|
53
|
+
)
|
|
54
|
+
report_skipped: bool = Field(
|
|
55
|
+
True,
|
|
56
|
+
description="Include skipped rows in import report"
|
|
57
|
+
)
|
|
58
|
+
skip_diff: bool = Field(
|
|
59
|
+
False,
|
|
60
|
+
description="Skip diff generation for faster imports (large datasets)"
|
|
61
|
+
)
|
|
62
|
+
use_transactions: bool = Field(
|
|
63
|
+
True,
|
|
64
|
+
description="Use database transactions for imports"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
# Validation and hooks (can be string paths or callables)
|
|
68
|
+
before_import: Optional[Union[str, Callable]] = Field(
|
|
69
|
+
None,
|
|
70
|
+
description="Hook called before import starts (receives dataset, dry_run)"
|
|
71
|
+
)
|
|
72
|
+
after_import: Optional[Union[str, Callable]] = Field(
|
|
73
|
+
None,
|
|
74
|
+
description="Hook called after import completes (receives dataset, result, dry_run)"
|
|
75
|
+
)
|
|
76
|
+
before_import_row: Optional[Union[str, Callable]] = Field(
|
|
77
|
+
None,
|
|
78
|
+
description="Hook called before each row import (receives row, row_number, dry_run)"
|
|
79
|
+
)
|
|
80
|
+
after_import_row: Optional[Union[str, Callable]] = Field(
|
|
81
|
+
None,
|
|
82
|
+
description="Hook called after each row import (receives row, row_result, row_number)"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
# Export options
|
|
86
|
+
export_order: List[str] = Field(
|
|
87
|
+
default_factory=list,
|
|
88
|
+
description="Field order in exported files (empty = model field order)"
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
# Field widgets/customization
|
|
92
|
+
field_widgets: Dict[str, Any] = Field(
|
|
93
|
+
default_factory=dict,
|
|
94
|
+
description="Custom widgets for fields (e.g., {'date': {'format': '%Y-%m-%d'}})"
|
|
95
|
+
)
|
|
96
|
+
|
|
97
|
+
# Batch processing
|
|
98
|
+
batch_size: Optional[int] = Field(
|
|
99
|
+
None,
|
|
100
|
+
description="Process imports in batches (for large datasets)"
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
def get_callable(self, hook_name: str) -> Optional[Callable]:
|
|
104
|
+
"""
|
|
105
|
+
Get callable for a hook by name.
|
|
106
|
+
|
|
107
|
+
Args:
|
|
108
|
+
hook_name: Name of the hook ('before_import', 'after_import_row', etc.)
|
|
109
|
+
|
|
110
|
+
Returns:
|
|
111
|
+
Callable function or None if not set
|
|
112
|
+
"""
|
|
113
|
+
hook_value = getattr(self, hook_name, None)
|
|
114
|
+
|
|
115
|
+
if hook_value is None:
|
|
116
|
+
return None
|
|
117
|
+
|
|
118
|
+
# If already a callable, return it
|
|
119
|
+
if callable(hook_value):
|
|
120
|
+
return hook_value
|
|
121
|
+
|
|
122
|
+
# If string, import it
|
|
123
|
+
if isinstance(hook_value, str):
|
|
124
|
+
import importlib
|
|
125
|
+
module_path, function_name = hook_value.rsplit('.', 1)
|
|
126
|
+
module = importlib.import_module(module_path)
|
|
127
|
+
return getattr(module, function_name)
|
|
128
|
+
|
|
129
|
+
return None
|
|
@@ -74,6 +74,12 @@ class Command(BaseCommand):
|
|
|
74
74
|
)
|
|
75
75
|
|
|
76
76
|
# Utility options
|
|
77
|
+
parser.add_argument(
|
|
78
|
+
"--no-build",
|
|
79
|
+
action="store_true",
|
|
80
|
+
help="Skip Next.js admin build (useful when calling from Makefile)",
|
|
81
|
+
)
|
|
82
|
+
|
|
77
83
|
parser.add_argument(
|
|
78
84
|
"--dry-run",
|
|
79
85
|
action="store_true",
|
|
@@ -515,7 +521,13 @@ class Command(BaseCommand):
|
|
|
515
521
|
# First copy API clients
|
|
516
522
|
self._copy_to_nextjs_admin(service)
|
|
517
523
|
# Then build Next.js (so clients are included in build)
|
|
518
|
-
|
|
524
|
+
# Skip build if --no-build flag is set
|
|
525
|
+
if not options.get("no_build"):
|
|
526
|
+
self._build_nextjs_admin()
|
|
527
|
+
else:
|
|
528
|
+
self.stdout.write(self.style.WARNING(
|
|
529
|
+
"\n⏭️ Skipping Next.js build (--no-build flag set)"
|
|
530
|
+
))
|
|
519
531
|
|
|
520
532
|
# Summary
|
|
521
533
|
self.stdout.write("\n" + "=" * 60)
|
|
@@ -4,15 +4,19 @@ Default Navigation Configuration for Django CFG Unfold
|
|
|
4
4
|
Provides default navigation sections based on enabled django-cfg modules.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
import logging
|
|
8
|
+
import traceback
|
|
9
|
+
from typing import Any, Dict, List, Optional
|
|
8
10
|
|
|
9
|
-
from django.urls import reverse_lazy
|
|
11
|
+
from django.urls import reverse_lazy, NoReverseMatch
|
|
10
12
|
|
|
11
13
|
from django_cfg.modules.django_admin.icons import Icons
|
|
12
14
|
from django_cfg.modules.base import BaseCfgModule
|
|
13
15
|
|
|
14
16
|
from .models.navigation import NavigationItem, NavigationSection
|
|
15
17
|
|
|
18
|
+
logger = logging.getLogger(__name__)
|
|
19
|
+
|
|
16
20
|
|
|
17
21
|
class NavigationManager(BaseCfgModule):
|
|
18
22
|
"""
|
|
@@ -39,19 +43,92 @@ class NavigationManager(BaseCfgModule):
|
|
|
39
43
|
self._config_loaded = True
|
|
40
44
|
return self._config
|
|
41
45
|
|
|
46
|
+
def _safe_reverse(self, url_name: str, fallback: Optional[str] = None) -> Optional[str]:
|
|
47
|
+
"""
|
|
48
|
+
Safely resolve URL with error logging.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
url_name: Django URL name to reverse
|
|
52
|
+
fallback: Optional fallback URL if reverse fails
|
|
53
|
+
|
|
54
|
+
Returns:
|
|
55
|
+
Resolved URL string or fallback, None if both fail
|
|
56
|
+
"""
|
|
57
|
+
try:
|
|
58
|
+
return str(reverse_lazy(url_name))
|
|
59
|
+
except NoReverseMatch as e:
|
|
60
|
+
logger.error(
|
|
61
|
+
f"Failed to reverse URL '{url_name}': {e}\n"
|
|
62
|
+
f"Traceback:\n{''.join(traceback.format_tb(e.__traceback__))}"
|
|
63
|
+
)
|
|
64
|
+
if fallback:
|
|
65
|
+
logger.warning(f"Using fallback URL: {fallback}")
|
|
66
|
+
return fallback
|
|
67
|
+
return None
|
|
68
|
+
except Exception as e:
|
|
69
|
+
logger.error(
|
|
70
|
+
f"Unexpected error reversing URL '{url_name}': {e}\n"
|
|
71
|
+
f"Traceback:\n{''.join(traceback.format_exc())}"
|
|
72
|
+
)
|
|
73
|
+
return fallback
|
|
74
|
+
|
|
75
|
+
def _create_nav_item(
|
|
76
|
+
self,
|
|
77
|
+
title: str,
|
|
78
|
+
icon: str,
|
|
79
|
+
url_name: str,
|
|
80
|
+
fallback_link: Optional[str] = None
|
|
81
|
+
) -> Optional[NavigationItem]:
|
|
82
|
+
"""
|
|
83
|
+
Create NavigationItem with safe URL resolution.
|
|
84
|
+
|
|
85
|
+
Args:
|
|
86
|
+
title: Navigation item title
|
|
87
|
+
icon: Icon identifier
|
|
88
|
+
url_name: Django URL name to reverse
|
|
89
|
+
fallback_link: Optional fallback URL
|
|
90
|
+
|
|
91
|
+
Returns:
|
|
92
|
+
NavigationItem or None if URL resolution fails
|
|
93
|
+
"""
|
|
94
|
+
link = self._safe_reverse(url_name, fallback_link)
|
|
95
|
+
if link is None:
|
|
96
|
+
logger.warning(f"Skipping navigation item '{title}' - URL '{url_name}' could not be resolved")
|
|
97
|
+
return None
|
|
98
|
+
|
|
99
|
+
return NavigationItem(title=title, icon=icon, link=link)
|
|
100
|
+
|
|
42
101
|
def get_navigation_config(self) -> List[Dict[str, Any]]:
|
|
43
102
|
"""Get complete default navigation configuration for Unfold sidebar."""
|
|
103
|
+
# Dashboard section with safe URL resolution
|
|
104
|
+
dashboard_items = []
|
|
105
|
+
|
|
106
|
+
# Overview
|
|
107
|
+
overview_item = self._create_nav_item("Overview", Icons.DASHBOARD, "admin:index")
|
|
108
|
+
if overview_item:
|
|
109
|
+
dashboard_items.append(overview_item)
|
|
110
|
+
|
|
111
|
+
# Settings
|
|
112
|
+
settings_item = self._create_nav_item("Settings", Icons.SETTINGS, "admin:constance_config_changelist")
|
|
113
|
+
if settings_item:
|
|
114
|
+
dashboard_items.append(settings_item)
|
|
115
|
+
|
|
116
|
+
# Health Check
|
|
117
|
+
health_item = self._create_nav_item("Health Check", Icons.HEALTH_AND_SAFETY, "django_cfg_drf_health", "/cfg/health/")
|
|
118
|
+
if health_item:
|
|
119
|
+
dashboard_items.append(health_item)
|
|
120
|
+
|
|
121
|
+
# Endpoints Status
|
|
122
|
+
endpoints_item = self._create_nav_item("Endpoints Status", Icons.API, "endpoints_status_drf", "/cfg/endpoints/")
|
|
123
|
+
if endpoints_item:
|
|
124
|
+
dashboard_items.append(endpoints_item)
|
|
125
|
+
|
|
44
126
|
navigation_sections = [
|
|
45
127
|
NavigationSection(
|
|
46
128
|
title="Dashboard",
|
|
47
129
|
separator=True,
|
|
48
130
|
collapsible=True,
|
|
49
|
-
items=
|
|
50
|
-
NavigationItem(title="Overview", icon=Icons.DASHBOARD, link=str(reverse_lazy("admin:index"))),
|
|
51
|
-
NavigationItem(title="Settings", icon=Icons.SETTINGS, link=str(reverse_lazy("admin:constance_config_changelist"))),
|
|
52
|
-
NavigationItem(title="Health Check", icon=Icons.HEALTH_AND_SAFETY, link=str(reverse_lazy("django_cfg_drf_health"))),
|
|
53
|
-
NavigationItem(title="Endpoints Status", icon=Icons.API, link=str(reverse_lazy("endpoints_status_drf"))),
|
|
54
|
-
]
|
|
131
|
+
items=dashboard_items
|
|
55
132
|
),
|
|
56
133
|
]
|
|
57
134
|
|
|
@@ -69,29 +146,51 @@ class NavigationManager(BaseCfgModule):
|
|
|
69
146
|
)
|
|
70
147
|
)
|
|
71
148
|
|
|
72
|
-
#
|
|
73
|
-
operations_items = []
|
|
74
|
-
|
|
75
|
-
# Background Tasks (if enabled)
|
|
149
|
+
# Background Tasks section (if enabled)
|
|
76
150
|
if self.should_enable_tasks():
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
151
|
+
tasks_items = []
|
|
152
|
+
|
|
153
|
+
tasks_items.append(
|
|
154
|
+
NavigationItem(title="Dashboard", icon=Icons.SETTINGS_APPLICATIONS, link="/cfg/admin/admin/tasks")
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# Try to add Tasks Logs with safe URL resolution
|
|
158
|
+
logs_item = self._create_nav_item(
|
|
159
|
+
title="Logs",
|
|
160
|
+
icon=Icons.TASK,
|
|
161
|
+
url_name="admin:django_cfg_tasks_tasklog_changelist",
|
|
162
|
+
fallback_link="/admin/django_cfg_tasks/tasklog/"
|
|
163
|
+
)
|
|
164
|
+
if logs_item:
|
|
165
|
+
tasks_items.append(logs_item)
|
|
166
|
+
|
|
167
|
+
navigation_sections.append(NavigationSection(
|
|
168
|
+
title="Background Tasks",
|
|
169
|
+
separator=True,
|
|
170
|
+
collapsible=True,
|
|
171
|
+
items=tasks_items
|
|
172
|
+
))
|
|
173
|
+
|
|
174
|
+
# System Operations section
|
|
175
|
+
system_items = []
|
|
81
176
|
|
|
82
177
|
# Maintenance Mode (if enabled)
|
|
83
178
|
if self.is_maintenance_enabled():
|
|
84
|
-
|
|
85
|
-
|
|
179
|
+
maintenance_item = self._create_nav_item(
|
|
180
|
+
title="Maintenance",
|
|
181
|
+
icon=Icons.BUILD,
|
|
182
|
+
url_name="admin:maintenance_cloudflaresite_changelist"
|
|
86
183
|
)
|
|
184
|
+
if maintenance_item:
|
|
185
|
+
system_items.append(maintenance_item)
|
|
87
186
|
|
|
88
|
-
# Add Operations section if there are any items
|
|
89
|
-
if
|
|
187
|
+
# Add System Operations section if there are any items
|
|
188
|
+
if system_items:
|
|
90
189
|
navigation_sections.append(NavigationSection(
|
|
91
|
-
title="Operations",
|
|
190
|
+
title="System Operations",
|
|
92
191
|
separator=True,
|
|
93
192
|
collapsible=True,
|
|
94
|
-
items=
|
|
193
|
+
items=system_items
|
|
95
194
|
))
|
|
96
195
|
|
|
97
196
|
# Add Accounts section if enabled
|
django_cfg/pyproject.toml
CHANGED
|
@@ -4,13 +4,13 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "django-cfg"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.108"
|
|
8
8
|
description = "Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "nextjs-admin", "react-admin", "websocket", "centrifugo", "real-time", "typescript-generation", "ai-agents", "enterprise-django", "django-settings", "type-safe-config", "modern-django",]
|
|
11
11
|
classifiers = [ "Development Status :: 4 - Beta", "Framework :: Django", "Framework :: Django :: 5.2", "Intended Audience :: Developers", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.12", "Programming Language :: Python :: 3.13", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content", "Topic :: Software Development :: Libraries :: Python Modules", "Topic :: System :: Systems Administration", "Typing :: Typed",]
|
|
12
12
|
requires-python = ">=3.12,<3.14"
|
|
13
|
-
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "djangorestframework>=3.16.0,<4.0", "djangorestframework-simplejwt>=5.5.0,<6.0", "djangorestframework-simplejwt[token-blacklist]>=5.5.0,<6.0", "drf-nested-routers>=0.94.0,<1.0", "django-filter>=25.0,<26.0", "django-ratelimit>=4.1.0,<5.0.0", "drf-spectacular>=0.28.0,<1.0", "drf-spectacular-sidecar>=2025.8.0,<2026.0", "django-json-widget>=2.0.0,<3.0", "django-import-export>=4.3.0,<5.0", "django-extensions>=4.1.0,<5.0", "django-constance>=4.3.0,<5.0", "django-unfold>=0.64.0,<1.0", "django-redis>=6.0.0,<7.0", "redis>=6.4.0,<7.0", "hiredis>=2.0.0,<4.0", "
|
|
13
|
+
dependencies = [ "pydantic>=2.11.0,<3.0", "pydantic[email]>=2.11.0,<3.0", "PyYAML>=6.0,<7.0", "click>=8.2.0,<9.0", "questionary>=2.1.0,<3.0", "rich>=14.0.0,<15.0", "cloudflare>=4.3.0,<5.0", "loguru>=0.7.0,<1.0", "colorlog>=6.9.0,<7.0", "cachetools>=5.3.0,<7.0", "toml>=0.10.2,<0.11.0", "ngrok>=1.5.1; python_version>='3.12'", "psycopg[binary,pool]>=3.2.0,<4.0", "dj-database-url>=3.0.0,<4.0", "whitenoise>=6.8.0,<7.0", "django-cors-headers>=4.7.0,<5.0", "djangorestframework>=3.16.0,<4.0", "djangorestframework-simplejwt>=5.5.0,<6.0", "djangorestframework-simplejwt[token-blacklist]>=5.5.0,<6.0", "drf-nested-routers>=0.94.0,<1.0", "django-filter>=25.0,<26.0", "django-ratelimit>=4.1.0,<5.0.0", "drf-spectacular>=0.28.0,<1.0", "drf-spectacular-sidecar>=2025.8.0,<2026.0", "django-json-widget>=2.0.0,<3.0", "django-import-export>=4.3.0,<5.0", "django-extensions>=4.1.0,<5.0", "django-constance>=4.3.0,<5.0", "django-unfold>=0.64.0,<1.0", "django-redis>=6.0.0,<7.0", "redis>=6.4.0,<7.0", "hiredis>=2.0.0,<4.0", "rearq>=0.2.0,<1.0", "setuptools>=75.0.0; python_version>='3.13'", "pyTelegramBotAPI>=4.28.0,<5.0", "coolname>=2.2.0,<3.0", "django-admin-rangefilter>=0.13.0,<1.0", "python-json-logger>=3.3.0,<4.0", "requests>=2.32.0,<3.0", "tiktoken>=0.11.0,<1.0", "openai>=1.107.0,<2.0", "twilio>=9.8.0,<10.0", "sendgrid>=6.12.0,<7.0", "beautifulsoup4>=4.13.0,<5.0", "lxml>=6.0.0,<7.0", "pgvector>=0.4.0,<1.0", "tenacity>=9.1.2,<10.0.0", "mypy (>=1.18.2,<2.0.0)", "django-tailwind[reload] (>=4.2.0,<5.0.0)", "jinja2 (>=3.1.6,<4.0.0)", "django-axes[ipware] (>=8.0.0,<9.0.0)", "pydantic-settings (>=2.11.0,<3.0.0)", "pytz>=2025.1", "httpx>=0.28.1,<1.0",]
|
|
14
14
|
[[project.authors]]
|
|
15
15
|
name = "Django-CFG Team"
|
|
16
16
|
email = "info@djangocfg.com"
|
django_cfg/registry/core.py
CHANGED
|
@@ -49,7 +49,7 @@ CORE_REGISTRY = {
|
|
|
49
49
|
|
|
50
50
|
# Task and queue models
|
|
51
51
|
"TaskConfig": ("django_cfg.models.tasks.config", "TaskConfig"),
|
|
52
|
-
"
|
|
52
|
+
"RearqConfig": ("django_cfg.models.tasks.config", "RearqConfig"),
|
|
53
53
|
|
|
54
54
|
# Payment system models (BaseCfgAutoModule)
|
|
55
55
|
"PaymentsConfig": ("django_cfg.models.payments.config", "PaymentsConfig"),
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-cfg
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.108
|
|
4
4
|
Summary: Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features.
|
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
|
6
6
|
Project-URL: Documentation, https://djangocfg.com
|
|
@@ -39,7 +39,6 @@ Requires-Dist: django-admin-rangefilter<1.0,>=0.13.0
|
|
|
39
39
|
Requires-Dist: django-axes[ipware]<9.0.0,>=8.0.0
|
|
40
40
|
Requires-Dist: django-constance<5.0,>=4.3.0
|
|
41
41
|
Requires-Dist: django-cors-headers<5.0,>=4.7.0
|
|
42
|
-
Requires-Dist: django-dramatiq<1.0,>=0.14.0
|
|
43
42
|
Requires-Dist: django-extensions<5.0,>=4.1.0
|
|
44
43
|
Requires-Dist: django-filter<26.0,>=25.0
|
|
45
44
|
Requires-Dist: django-import-export<5.0,>=4.3.0
|
|
@@ -51,11 +50,11 @@ Requires-Dist: django-unfold<1.0,>=0.64.0
|
|
|
51
50
|
Requires-Dist: djangorestframework-simplejwt<6.0,>=5.5.0
|
|
52
51
|
Requires-Dist: djangorestframework-simplejwt[token-blacklist]<6.0,>=5.5.0
|
|
53
52
|
Requires-Dist: djangorestframework<4.0,>=3.16.0
|
|
54
|
-
Requires-Dist: dramatiq[redis]<2.0,>=1.18.0
|
|
55
53
|
Requires-Dist: drf-nested-routers<1.0,>=0.94.0
|
|
56
54
|
Requires-Dist: drf-spectacular-sidecar<2026.0,>=2025.8.0
|
|
57
55
|
Requires-Dist: drf-spectacular<1.0,>=0.28.0
|
|
58
56
|
Requires-Dist: hiredis<4.0,>=2.0.0
|
|
57
|
+
Requires-Dist: httpx<1.0,>=0.28.1
|
|
59
58
|
Requires-Dist: jinja2<4.0.0,>=3.1.6
|
|
60
59
|
Requires-Dist: loguru<1.0,>=0.7.0
|
|
61
60
|
Requires-Dist: lxml<7.0,>=6.0.0
|
|
@@ -69,12 +68,15 @@ Requires-Dist: pydantic<3.0,>=2.11.0
|
|
|
69
68
|
Requires-Dist: pydantic[email]<3.0,>=2.11.0
|
|
70
69
|
Requires-Dist: pytelegrambotapi<5.0,>=4.28.0
|
|
71
70
|
Requires-Dist: python-json-logger<4.0,>=3.3.0
|
|
71
|
+
Requires-Dist: pytz>=2025.1
|
|
72
72
|
Requires-Dist: pyyaml<7.0,>=6.0
|
|
73
73
|
Requires-Dist: questionary<3.0,>=2.1.0
|
|
74
|
+
Requires-Dist: rearq<1.0,>=0.2.0
|
|
74
75
|
Requires-Dist: redis<7.0,>=6.4.0
|
|
75
76
|
Requires-Dist: requests<3.0,>=2.32.0
|
|
76
77
|
Requires-Dist: rich<15.0,>=14.0.0
|
|
77
78
|
Requires-Dist: sendgrid<7.0,>=6.12.0
|
|
79
|
+
Requires-Dist: setuptools>=75.0.0; python_version >= '3.13'
|
|
78
80
|
Requires-Dist: tenacity<10.0.0,>=9.1.2
|
|
79
81
|
Requires-Dist: tiktoken<1.0,>=0.11.0
|
|
80
82
|
Requires-Dist: toml<0.11.0,>=0.10.2
|