django-cfg 1.1.82__py3-none-any.whl → 1.2.0__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.
- django_cfg/__init__.py +20 -448
- django_cfg/apps/accounts/README.md +3 -3
- django_cfg/apps/accounts/admin/__init__.py +0 -2
- django_cfg/apps/accounts/admin/activity.py +2 -9
- django_cfg/apps/accounts/admin/filters.py +0 -42
- django_cfg/apps/accounts/admin/inlines.py +8 -8
- django_cfg/apps/accounts/admin/otp.py +5 -5
- django_cfg/apps/accounts/admin/registration_source.py +1 -8
- django_cfg/apps/accounts/admin/user.py +12 -20
- django_cfg/apps/accounts/managers/user_manager.py +2 -129
- django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
- django_cfg/apps/accounts/models.py +3 -123
- django_cfg/apps/accounts/serializers/otp.py +40 -44
- django_cfg/apps/accounts/serializers/profile.py +0 -2
- django_cfg/apps/accounts/services/otp_service.py +98 -186
- django_cfg/apps/accounts/signals.py +25 -15
- django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
- django_cfg/apps/accounts/views/otp.py +35 -36
- django_cfg/apps/agents/README.md +129 -0
- django_cfg/apps/agents/__init__.py +68 -0
- django_cfg/apps/agents/admin/__init__.py +17 -0
- django_cfg/apps/agents/admin/execution_admin.py +460 -0
- django_cfg/apps/agents/admin/registry_admin.py +360 -0
- django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
- django_cfg/apps/agents/apps.py +29 -0
- django_cfg/apps/agents/core/__init__.py +20 -0
- django_cfg/apps/agents/core/agent.py +281 -0
- django_cfg/apps/agents/core/dependencies.py +154 -0
- django_cfg/apps/agents/core/exceptions.py +66 -0
- django_cfg/apps/agents/core/models.py +106 -0
- django_cfg/apps/agents/core/orchestrator.py +391 -0
- django_cfg/apps/agents/examples/__init__.py +3 -0
- django_cfg/apps/agents/examples/simple_example.py +161 -0
- django_cfg/apps/agents/integration/__init__.py +14 -0
- django_cfg/apps/agents/integration/middleware.py +80 -0
- django_cfg/apps/agents/integration/registry.py +345 -0
- django_cfg/apps/agents/integration/signals.py +50 -0
- django_cfg/apps/agents/management/__init__.py +3 -0
- django_cfg/apps/agents/management/commands/__init__.py +3 -0
- django_cfg/apps/agents/management/commands/create_agent.py +365 -0
- django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
- django_cfg/apps/agents/managers/__init__.py +23 -0
- django_cfg/apps/agents/managers/execution.py +236 -0
- django_cfg/apps/agents/managers/registry.py +254 -0
- django_cfg/apps/agents/managers/toolsets.py +496 -0
- django_cfg/apps/agents/migrations/0001_initial.py +286 -0
- django_cfg/apps/agents/migrations/__init__.py +5 -0
- django_cfg/apps/agents/models/__init__.py +15 -0
- django_cfg/apps/agents/models/execution.py +215 -0
- django_cfg/apps/agents/models/registry.py +220 -0
- django_cfg/apps/agents/models/toolsets.py +305 -0
- django_cfg/apps/agents/patterns/__init__.py +24 -0
- django_cfg/apps/agents/patterns/content_agents.py +234 -0
- django_cfg/apps/agents/toolsets/__init__.py +15 -0
- django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
- django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
- django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
- django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
- django_cfg/apps/agents/urls.py +46 -0
- django_cfg/apps/knowbase/README.md +150 -0
- django_cfg/apps/knowbase/__init__.py +27 -0
- django_cfg/apps/knowbase/admin/__init__.py +23 -0
- django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
- django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
- django_cfg/apps/knowbase/admin/document_admin.py +650 -0
- django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
- django_cfg/apps/knowbase/apps.py +81 -0
- django_cfg/apps/knowbase/config/README.md +176 -0
- django_cfg/apps/knowbase/config/__init__.py +51 -0
- django_cfg/apps/knowbase/config/constance_fields.py +186 -0
- django_cfg/apps/knowbase/config/constance_settings.py +200 -0
- django_cfg/apps/knowbase/config/settings.py +444 -0
- django_cfg/apps/knowbase/examples/__init__.py +3 -0
- django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
- django_cfg/apps/knowbase/management/__init__.py +0 -0
- django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
- django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
- django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
- django_cfg/apps/knowbase/managers/__init__.py +22 -0
- django_cfg/apps/knowbase/managers/archive.py +426 -0
- django_cfg/apps/knowbase/managers/base.py +32 -0
- django_cfg/apps/knowbase/managers/chat.py +141 -0
- django_cfg/apps/knowbase/managers/document.py +203 -0
- django_cfg/apps/knowbase/managers/external_data.py +471 -0
- django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
- django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
- django_cfg/apps/knowbase/migrations/__init__.py +5 -0
- django_cfg/apps/knowbase/mixins/__init__.py +15 -0
- django_cfg/apps/knowbase/mixins/config.py +108 -0
- django_cfg/apps/knowbase/mixins/creator.py +81 -0
- django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
- django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
- django_cfg/apps/knowbase/mixins/service.py +362 -0
- django_cfg/apps/knowbase/models/__init__.py +41 -0
- django_cfg/apps/knowbase/models/archive.py +599 -0
- django_cfg/apps/knowbase/models/base.py +58 -0
- django_cfg/apps/knowbase/models/chat.py +157 -0
- django_cfg/apps/knowbase/models/document.py +267 -0
- django_cfg/apps/knowbase/models/external_data.py +376 -0
- django_cfg/apps/knowbase/serializers/__init__.py +68 -0
- django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
- django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
- django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
- django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
- django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
- django_cfg/apps/knowbase/services/__init__.py +40 -0
- django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
- django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
- django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
- django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
- django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
- django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
- django_cfg/apps/knowbase/services/base.py +53 -0
- django_cfg/apps/knowbase/services/chat_service.py +239 -0
- django_cfg/apps/knowbase/services/document_service.py +144 -0
- django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
- django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
- django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
- django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
- django_cfg/apps/knowbase/services/embedding/models.py +229 -0
- django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
- django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
- django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
- django_cfg/apps/knowbase/services/search_service.py +293 -0
- django_cfg/apps/knowbase/signals/__init__.py +21 -0
- django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
- django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
- django_cfg/apps/knowbase/signals/document_signals.py +143 -0
- django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
- django_cfg/apps/knowbase/tasks/__init__.py +39 -0
- django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
- django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
- django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
- django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
- django_cfg/apps/knowbase/urls.py +43 -0
- django_cfg/apps/knowbase/utils/__init__.py +12 -0
- django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
- django_cfg/apps/knowbase/utils/text_processing.py +375 -0
- django_cfg/apps/knowbase/utils/validation.py +99 -0
- django_cfg/apps/knowbase/views/__init__.py +28 -0
- django_cfg/apps/knowbase/views/archive_views.py +469 -0
- django_cfg/apps/knowbase/views/base.py +49 -0
- django_cfg/apps/knowbase/views/chat_views.py +181 -0
- django_cfg/apps/knowbase/views/document_views.py +183 -0
- django_cfg/apps/knowbase/views/public_views.py +129 -0
- django_cfg/apps/leads/admin.py +70 -0
- django_cfg/apps/newsletter/admin.py +234 -0
- django_cfg/apps/newsletter/admin_filters.py +124 -0
- django_cfg/apps/support/admin.py +196 -0
- django_cfg/apps/support/admin_filters.py +71 -0
- django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
- django_cfg/apps/urls.py +5 -4
- django_cfg/cli/README.md +1 -1
- django_cfg/cli/commands/create_project.py +2 -2
- django_cfg/cli/commands/info.py +1 -1
- django_cfg/config.py +44 -0
- django_cfg/core/config.py +29 -82
- django_cfg/core/environment.py +1 -1
- django_cfg/core/generation.py +19 -107
- django_cfg/{integration.py → core/integration.py} +18 -16
- django_cfg/core/validation.py +1 -1
- django_cfg/management/__init__.py +1 -1
- django_cfg/management/commands/__init__.py +1 -1
- django_cfg/management/commands/auto_generate.py +482 -0
- django_cfg/management/commands/migrator.py +19 -101
- django_cfg/management/commands/test_email.py +1 -1
- django_cfg/middleware/README.md +0 -158
- django_cfg/middleware/__init__.py +0 -2
- django_cfg/middleware/user_activity.py +3 -3
- django_cfg/models/api.py +145 -0
- django_cfg/models/base.py +287 -0
- django_cfg/models/cache.py +4 -4
- django_cfg/models/constance.py +25 -88
- django_cfg/models/database.py +9 -9
- django_cfg/models/drf.py +3 -36
- django_cfg/models/email.py +163 -0
- django_cfg/models/environment.py +276 -0
- django_cfg/models/limits.py +1 -1
- django_cfg/models/logging.py +366 -0
- django_cfg/models/revolution.py +41 -2
- django_cfg/models/security.py +125 -0
- django_cfg/models/services.py +1 -1
- django_cfg/modules/__init__.py +2 -56
- django_cfg/modules/base.py +78 -52
- django_cfg/modules/django_currency/service.py +2 -2
- django_cfg/modules/django_email.py +2 -2
- django_cfg/modules/django_health.py +267 -0
- django_cfg/modules/django_llm/llm/client.py +79 -17
- django_cfg/modules/django_llm/translator/translator.py +2 -2
- django_cfg/modules/django_logger.py +2 -2
- django_cfg/modules/django_ngrok.py +2 -2
- django_cfg/modules/django_tasks.py +68 -3
- django_cfg/modules/django_telegram.py +3 -3
- django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
- django_cfg/modules/django_twilio/service.py +2 -2
- django_cfg/modules/django_twilio/simple_service.py +2 -2
- django_cfg/modules/django_twilio/twilio_service.py +2 -2
- django_cfg/modules/django_unfold/__init__.py +69 -0
- django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
- django_cfg/modules/django_unfold/dashboard.py +278 -0
- django_cfg/modules/django_unfold/icons/README.md +145 -0
- django_cfg/modules/django_unfold/icons/__init__.py +12 -0
- django_cfg/modules/django_unfold/icons/constants.py +2851 -0
- django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
- django_cfg/modules/django_unfold/models/__init__.py +42 -0
- django_cfg/modules/django_unfold/models/config.py +601 -0
- django_cfg/modules/django_unfold/models/dashboard.py +206 -0
- django_cfg/modules/django_unfold/models/dropdown.py +40 -0
- django_cfg/modules/django_unfold/models/navigation.py +73 -0
- django_cfg/modules/django_unfold/models/tabs.py +25 -0
- django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
- django_cfg/modules/django_unfold/utils.py +140 -0
- django_cfg/registry/__init__.py +23 -0
- django_cfg/registry/core.py +61 -0
- django_cfg/registry/exceptions.py +11 -0
- django_cfg/registry/modules.py +12 -0
- django_cfg/registry/services.py +26 -0
- django_cfg/registry/third_party.py +52 -0
- django_cfg/routing/__init__.py +19 -0
- django_cfg/routing/callbacks.py +198 -0
- django_cfg/routing/routers.py +48 -0
- django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
- django_cfg/templatetags/__init__.py +0 -0
- django_cfg/templatetags/django_cfg.py +33 -0
- django_cfg/urls.py +33 -0
- django_cfg/utils/path_resolution.py +1 -1
- django_cfg/utils/smart_defaults.py +7 -61
- django_cfg/utils/toolkit.py +663 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
- django_cfg-1.2.0.dist-info/RECORD +441 -0
- django_cfg/archive/django_sample.zip +0 -0
- django_cfg/models/unfold.py +0 -271
- django_cfg/modules/unfold/__init__.py +0 -29
- django_cfg/modules/unfold/dashboard.py +0 -318
- django_cfg/pyproject.toml +0 -370
- django_cfg/routers.py +0 -83
- django_cfg-1.1.82.dist-info/RECORD +0 -278
- /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
- /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
- /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
- /django_cfg/{version_check.py → utils/version_check.py} +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.1.82.dist-info → django_cfg-1.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,52 @@
|
|
1
|
+
"""
|
2
|
+
Third-party integrations registry.
|
3
|
+
"""
|
4
|
+
|
5
|
+
THIRD_PARTY_REGISTRY = {
|
6
|
+
# Django Revolution
|
7
|
+
"RevolutionConfig": ("django_cfg.models.revolution", "RevolutionConfig"),
|
8
|
+
"APIZone": ("django_revolution.config", "ZoneModel"),
|
9
|
+
"ZoneModel": ("django_revolution.config", "ZoneModel"),
|
10
|
+
"ZoneConfig": ("django_revolution.app_config", "ZoneConfig"),
|
11
|
+
"DjangoRevolutionSettings": ("django_revolution.config", "DjangoRevolutionSettings"),
|
12
|
+
|
13
|
+
# Unfold Admin
|
14
|
+
"UnfoldConfig": ("django_cfg.modules.django_unfold.models.config", "UnfoldConfig"),
|
15
|
+
"UnfoldTheme": ("django_cfg.modules.django_unfold.models.config", "UnfoldTheme"),
|
16
|
+
"UnfoldThemeConfig": ("django_cfg.modules.django_unfold.models.config", "UnfoldThemeConfig"),
|
17
|
+
"UnfoldColors": ("django_cfg.modules.django_unfold.models.config", "UnfoldColors"),
|
18
|
+
"UnfoldSidebar": ("django_cfg.modules.django_unfold.models.config", "UnfoldSidebar"),
|
19
|
+
"UnfoldDashboardConfig": ("django_cfg.modules.django_unfold.models.config", "UnfoldDashboardConfig"),
|
20
|
+
"NavigationItem": ("django_cfg.modules.django_unfold.models.navigation", "NavigationItem"),
|
21
|
+
"NavigationSection": ("django_cfg.modules.django_unfold.models.navigation", "NavigationSection"),
|
22
|
+
"NavigationItemType": ("django_cfg.modules.django_unfold.models.navigation", "NavigationItemType"),
|
23
|
+
"SiteDropdownItem": ("django_cfg.modules.django_unfold.models.dropdown", "SiteDropdownItem"),
|
24
|
+
"StatCard": ("django_cfg.modules.django_unfold.models.dashboard", "StatCard"),
|
25
|
+
"SystemHealthItem": ("django_cfg.modules.django_unfold.models.dashboard", "SystemHealthItem"),
|
26
|
+
"QuickAction": ("django_cfg.modules.django_unfold.models.dashboard", "QuickAction"),
|
27
|
+
"DashboardWidget": ("django_cfg.modules.django_unfold.models.dashboard", "DashboardWidget"),
|
28
|
+
"DashboardData": ("django_cfg.modules.django_unfold.models.dashboard", "DashboardData"),
|
29
|
+
"ChartDataset": ("django_cfg.modules.django_unfold.models.dashboard", "ChartDataset"),
|
30
|
+
"ChartData": ("django_cfg.modules.django_unfold.models.dashboard", "ChartData"),
|
31
|
+
"TabConfiguration": ("django_cfg.modules.django_unfold.models.tabs", "TabConfiguration"),
|
32
|
+
"TabItem": ("django_cfg.modules.django_unfold.models.tabs", "TabItem"),
|
33
|
+
|
34
|
+
# Django REST Framework
|
35
|
+
"DRFConfig": ("django_cfg.models.drf", "DRFConfig"),
|
36
|
+
"SpectacularConfig": ("django_cfg.models.drf", "SpectacularConfig"),
|
37
|
+
"SwaggerUISettings": ("django_cfg.models.drf", "SwaggerUISettings"),
|
38
|
+
"RedocUISettings": ("django_cfg.models.drf", "RedocUISettings"),
|
39
|
+
|
40
|
+
# Constance
|
41
|
+
"ConstanceConfig": ("django_cfg.models.constance", "ConstanceConfig"),
|
42
|
+
"ConstanceField": ("django_cfg.models.constance", "ConstanceField"),
|
43
|
+
|
44
|
+
# Ngrok
|
45
|
+
"NgrokConfig": ("django_cfg.models.ngrok", "NgrokConfig"),
|
46
|
+
"NgrokAuthConfig": ("django_cfg.models.ngrok", "NgrokAuthConfig"),
|
47
|
+
"NgrokTunnelConfig": ("django_cfg.models.ngrok", "NgrokTunnelConfig"),
|
48
|
+
|
49
|
+
# Material Icons
|
50
|
+
"Icons": ("django_cfg.modules.django_unfold.icons", "Icons"),
|
51
|
+
"IconCategories": ("django_cfg.modules.django_unfold.icons", "IconCategories"),
|
52
|
+
}
|
@@ -0,0 +1,19 @@
|
|
1
|
+
"""
|
2
|
+
Django-CFG Routing
|
3
|
+
|
4
|
+
URL routing and callback utilities.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from .routers import *
|
8
|
+
from .callbacks import *
|
9
|
+
|
10
|
+
__all__ = [
|
11
|
+
# From routers
|
12
|
+
"DynamicRouter",
|
13
|
+
"APIRouter",
|
14
|
+
"AdminRouter",
|
15
|
+
|
16
|
+
# From callbacks
|
17
|
+
"health_callback",
|
18
|
+
"status_callback",
|
19
|
+
]
|
@@ -0,0 +1,198 @@
|
|
1
|
+
"""
|
2
|
+
Dashboard Callback System
|
3
|
+
|
4
|
+
Provides callback utilities for Unfold dashboard integration.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from typing import Dict, Any, List, Optional, Callable
|
8
|
+
from datetime import datetime, timedelta
|
9
|
+
from django.http import HttpRequest
|
10
|
+
from django.contrib.auth import get_user_model
|
11
|
+
from django.contrib.contenttypes.models import ContentType
|
12
|
+
from django.db import connection
|
13
|
+
from django.conf import settings
|
14
|
+
from ..modules.base import BaseCfgModule
|
15
|
+
|
16
|
+
|
17
|
+
def dashboard_callback(request: HttpRequest, context: Dict[str, Any]) -> Dict[str, Any]:
|
18
|
+
"""
|
19
|
+
Default dashboard callback for Unfold admin.
|
20
|
+
|
21
|
+
Returns enhanced context with dashboard data.
|
22
|
+
"""
|
23
|
+
User = get_user_model()
|
24
|
+
|
25
|
+
# Get basic stats
|
26
|
+
user_count = User.objects.count()
|
27
|
+
|
28
|
+
# Database info
|
29
|
+
with connection.cursor() as cursor:
|
30
|
+
cursor.execute("SELECT COUNT(*) FROM django_session")
|
31
|
+
session_count = cursor.fetchone()[0]
|
32
|
+
|
33
|
+
# Add dashboard data to context
|
34
|
+
context.update({
|
35
|
+
"dashboard": [
|
36
|
+
{
|
37
|
+
"title": "System Overview",
|
38
|
+
"metric": f"{user_count} users",
|
39
|
+
"footer": f"{session_count} active sessions",
|
40
|
+
"chart": {
|
41
|
+
"labels": ["Users", "Sessions"],
|
42
|
+
"data": [user_count, session_count],
|
43
|
+
}
|
44
|
+
},
|
45
|
+
{
|
46
|
+
"title": "Quick Actions",
|
47
|
+
"metric": "Admin Tools",
|
48
|
+
"footer": "Manage your system",
|
49
|
+
"link": "/admin/",
|
50
|
+
}
|
51
|
+
]
|
52
|
+
})
|
53
|
+
|
54
|
+
return context
|
55
|
+
|
56
|
+
|
57
|
+
def environment_callback(request: HttpRequest) -> Dict[str, Any]:
|
58
|
+
"""
|
59
|
+
Environment callback for Unfold admin.
|
60
|
+
|
61
|
+
Returns environment information and system status.
|
62
|
+
"""
|
63
|
+
|
64
|
+
|
65
|
+
# Use BaseCfgModule to get config
|
66
|
+
base_module = BaseCfgModule()
|
67
|
+
config = base_module.get_config()
|
68
|
+
|
69
|
+
return {
|
70
|
+
"environment": getattr(config, 'environment', 'development'),
|
71
|
+
"debug": getattr(config, 'debug', False),
|
72
|
+
"version": getattr(settings, 'VERSION', '1.0.0'),
|
73
|
+
"database": {
|
74
|
+
"engine": "PostgreSQL" if config and hasattr(config, 'database_default') else "Unknown",
|
75
|
+
"name": config.database_default.name if config and hasattr(config, 'database_default') else "Unknown",
|
76
|
+
},
|
77
|
+
"cache": {
|
78
|
+
"backend": "Redis" if config and hasattr(config, 'cache_default') else "default",
|
79
|
+
},
|
80
|
+
"features": {
|
81
|
+
"unfold": True, # Unfold always enabled
|
82
|
+
"revolution": True, # Revolution always enabled
|
83
|
+
"constance": getattr(config, 'enable_constance', False) if config else False,
|
84
|
+
}
|
85
|
+
}
|
86
|
+
|
87
|
+
|
88
|
+
def permission_callback(request: HttpRequest) -> Dict[str, Any]:
|
89
|
+
"""
|
90
|
+
Permission callback for Unfold admin.
|
91
|
+
|
92
|
+
Returns user permission information.
|
93
|
+
"""
|
94
|
+
if not request.user.is_authenticated:
|
95
|
+
return {"permissions": [], "groups": []}
|
96
|
+
|
97
|
+
user_permissions = list(request.user.get_all_permissions())
|
98
|
+
user_groups = list(request.user.groups.values_list('name', flat=True))
|
99
|
+
|
100
|
+
return {
|
101
|
+
"permissions": user_permissions,
|
102
|
+
"groups": user_groups,
|
103
|
+
"is_staff": request.user.is_staff,
|
104
|
+
"is_superuser": request.user.is_superuser,
|
105
|
+
}
|
106
|
+
|
107
|
+
|
108
|
+
def search_callback(request: HttpRequest, query: str) -> List[Dict[str, Any]]:
|
109
|
+
"""
|
110
|
+
Search callback for Unfold admin.
|
111
|
+
|
112
|
+
Provides search functionality across models.
|
113
|
+
"""
|
114
|
+
|
115
|
+
|
116
|
+
results = []
|
117
|
+
|
118
|
+
if len(query) < 2:
|
119
|
+
return results
|
120
|
+
|
121
|
+
# Search users
|
122
|
+
User = get_user_model()
|
123
|
+
users = User.objects.filter(
|
124
|
+
username__icontains=query
|
125
|
+
).values('id', 'username', 'email')[:5]
|
126
|
+
|
127
|
+
for user in users:
|
128
|
+
results.append({
|
129
|
+
"title": f"User: {user['username']}",
|
130
|
+
"url": f"/admin/auth/user/{user['id']}/change/",
|
131
|
+
"description": user.get('email', ''),
|
132
|
+
})
|
133
|
+
|
134
|
+
# Search content types (as a proxy for apps/models)
|
135
|
+
content_types = ContentType.objects.filter(
|
136
|
+
model__icontains=query
|
137
|
+
).values('app_label', 'model')[:5]
|
138
|
+
|
139
|
+
for ct in content_types:
|
140
|
+
results.append({
|
141
|
+
"title": f"Model: {ct['app_label']}.{ct['model']}",
|
142
|
+
"url": f"/admin/{ct['app_label']}/{ct['model']}/",
|
143
|
+
"description": f"Manage {ct['model']} objects",
|
144
|
+
})
|
145
|
+
|
146
|
+
return results
|
147
|
+
|
148
|
+
|
149
|
+
def badge_callback(request: HttpRequest) -> List[Dict[str, Any]]:
|
150
|
+
"""
|
151
|
+
Badge callback for Unfold admin.
|
152
|
+
|
153
|
+
Returns notification badges and counters.
|
154
|
+
"""
|
155
|
+
from django.contrib.auth import get_user_model
|
156
|
+
|
157
|
+
User = get_user_model()
|
158
|
+
|
159
|
+
# Count new users in last 24 hours
|
160
|
+
from datetime import datetime, timedelta
|
161
|
+
yesterday = datetime.now() - timedelta(days=1)
|
162
|
+
new_users = User.objects.filter(date_joined__gte=yesterday).count()
|
163
|
+
|
164
|
+
badges = []
|
165
|
+
|
166
|
+
if new_users > 0:
|
167
|
+
badges.append({
|
168
|
+
"title": "New Users",
|
169
|
+
"count": new_users,
|
170
|
+
"color": "primary",
|
171
|
+
"url": "/admin/auth/user/?date_joined__gte=" + yesterday.strftime('%Y-%m-%d'),
|
172
|
+
})
|
173
|
+
|
174
|
+
# Add system health badge
|
175
|
+
badges.append({
|
176
|
+
"title": "System",
|
177
|
+
"count": "OK",
|
178
|
+
"color": "success",
|
179
|
+
"url": "/admin/",
|
180
|
+
})
|
181
|
+
|
182
|
+
return badges
|
183
|
+
|
184
|
+
|
185
|
+
# Helper function to register callbacks in Unfold config
|
186
|
+
def get_unfold_callbacks() -> Dict[str, str]:
|
187
|
+
"""
|
188
|
+
Get callback function paths for Unfold configuration.
|
189
|
+
|
190
|
+
Returns dictionary mapping callback types to function paths.
|
191
|
+
"""
|
192
|
+
return {
|
193
|
+
"dashboard_callback": "django_cfg.routing.callbacks.dashboard_callback",
|
194
|
+
"environment_callback": "django_cfg.routing.callbacks.environment_callback",
|
195
|
+
"permission_callback": "django_cfg.routing.callbacks.permission_callback",
|
196
|
+
"search_callback": "django_cfg.routing.callbacks.search_callback",
|
197
|
+
"badge_callback": "django_cfg.routing.callbacks.badge_callback",
|
198
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
"""
|
2
|
+
Database Router for Django Config Toolkit
|
3
|
+
|
4
|
+
Simple and reliable database routing.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from django.conf import settings
|
8
|
+
|
9
|
+
|
10
|
+
class DatabaseRouter:
|
11
|
+
"""
|
12
|
+
Simple database router that routes based on app labels.
|
13
|
+
|
14
|
+
Uses DATABASE_ROUTING_RULES setting to determine which apps
|
15
|
+
should use which databases.
|
16
|
+
"""
|
17
|
+
|
18
|
+
def db_for_read(self, model, **hints):
|
19
|
+
"""Route reads to correct database."""
|
20
|
+
rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
|
21
|
+
return rules.get(model._meta.app_label)
|
22
|
+
|
23
|
+
def db_for_write(self, model, **hints):
|
24
|
+
"""Route writes to correct database."""
|
25
|
+
rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
|
26
|
+
return rules.get(model._meta.app_label)
|
27
|
+
|
28
|
+
def allow_relation(self, obj1, obj2, **hints):
|
29
|
+
"""Allow relations between same database."""
|
30
|
+
rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
|
31
|
+
db1 = rules.get(obj1._meta.app_label)
|
32
|
+
db2 = rules.get(obj2._meta.app_label)
|
33
|
+
return db1 == db2 if db1 and db2 else None
|
34
|
+
|
35
|
+
def allow_migrate(self, db, app_label, **hints):
|
36
|
+
"""Allow migrations to correct database."""
|
37
|
+
rules = getattr(settings, 'DATABASE_ROUTING_RULES', {})
|
38
|
+
target_db = rules.get(app_label)
|
39
|
+
|
40
|
+
if target_db:
|
41
|
+
# This app IS configured in the rules
|
42
|
+
return db == target_db
|
43
|
+
elif db in rules.values():
|
44
|
+
# This app is NOT configured, but the target DB is used by other apps
|
45
|
+
return db == 'default'
|
46
|
+
|
47
|
+
# Allow migration to default
|
48
|
+
return None
|
@@ -429,15 +429,14 @@
|
|
429
429
|
<!-- Footer Section -->
|
430
430
|
<div class="text-center py-8 border-t border-base-200 dark:border-base-700 mt-5">
|
431
431
|
<p class="text-sm text-font-subtle-light dark:text-font-subtle-dark">
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
|
439
|
-
|
440
|
-
</a>
|
432
|
+
{% load django_cfg %}
|
433
|
+
<a href="{% lib_site_url %}" class="text-primary-600 hover:text-primary-700 font-medium">
|
434
|
+
{% lib_name %}
|
435
|
+
</a>
|
436
|
+
<span class="mx-2">•</span>
|
437
|
+
<a href="{% lib_health_url %}" class="text-primary-600 hover:text-primary-700">
|
438
|
+
System Health
|
439
|
+
</a>
|
441
440
|
</p>
|
442
441
|
</div>
|
443
442
|
|
File without changes
|
@@ -0,0 +1,33 @@
|
|
1
|
+
"""
|
2
|
+
Django-CFG Template Tags
|
3
|
+
|
4
|
+
Provides template tags for accessing django-cfg configuration constants.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from django import template
|
8
|
+
|
9
|
+
register = template.Library()
|
10
|
+
|
11
|
+
|
12
|
+
@register.simple_tag
|
13
|
+
def lib_name():
|
14
|
+
"""Get the library name."""
|
15
|
+
# Lazy import to avoid AppRegistryNotReady error
|
16
|
+
from django_cfg.config import LIB_NAME
|
17
|
+
return LIB_NAME
|
18
|
+
|
19
|
+
|
20
|
+
@register.simple_tag
|
21
|
+
def lib_site_url():
|
22
|
+
"""Get the library site URL."""
|
23
|
+
# Lazy import to avoid AppRegistryNotReady error
|
24
|
+
from django_cfg.config import LIB_SITE_URL
|
25
|
+
return LIB_SITE_URL
|
26
|
+
|
27
|
+
|
28
|
+
@register.simple_tag
|
29
|
+
def lib_health_url():
|
30
|
+
"""Get the library health URL."""
|
31
|
+
# Lazy import to avoid AppRegistryNotReady error
|
32
|
+
from django_cfg.config import LIB_HEALTH_URL
|
33
|
+
return LIB_HEALTH_URL
|
django_cfg/urls.py
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
"""
|
2
|
+
URL Configuration for Django Config Toolkit
|
3
|
+
|
4
|
+
Provides URL patterns for health checks and other toolkit endpoints.
|
5
|
+
"""
|
6
|
+
|
7
|
+
from django.urls import path, include
|
8
|
+
from .health import HealthCheckView, SimpleHealthView
|
9
|
+
|
10
|
+
|
11
|
+
app_name = 'django_cfg'
|
12
|
+
|
13
|
+
urlpatterns = [
|
14
|
+
# Health check endpoints
|
15
|
+
path('health/', HealthCheckView.as_view(), name='health-check'),
|
16
|
+
path('health/simple/', SimpleHealthView.as_view(), name='simple-health'),
|
17
|
+
]
|
18
|
+
|
19
|
+
|
20
|
+
def get_toolkit_urls():
|
21
|
+
"""
|
22
|
+
Get URL patterns for Django Config Toolkit.
|
23
|
+
|
24
|
+
Include in your main urls.py:
|
25
|
+
|
26
|
+
from django_cfg.urls import get_toolkit_urls
|
27
|
+
|
28
|
+
urlpatterns = [
|
29
|
+
path('admin/', admin.site.urls),
|
30
|
+
path('toolkit/', include(get_toolkit_urls())),
|
31
|
+
]
|
32
|
+
"""
|
33
|
+
return urlpatterns
|
@@ -11,9 +11,9 @@ Following CRITICAL_REQUIREMENTS.md:
|
|
11
11
|
from typing import Dict, Any, Optional, List
|
12
12
|
from pathlib import Path
|
13
13
|
|
14
|
-
from django_cfg.models.cache import
|
14
|
+
from django_cfg.models.cache import CacheConfig
|
15
15
|
from django_cfg.models.services import EmailConfig
|
16
|
-
from django_cfg.exceptions import ConfigurationError
|
16
|
+
from django_cfg.core.exceptions import ConfigurationError
|
17
17
|
|
18
18
|
|
19
19
|
class SmartDefaults:
|
@@ -30,10 +30,10 @@ class SmartDefaults:
|
|
30
30
|
@classmethod
|
31
31
|
def configure_cache_backend(
|
32
32
|
cls,
|
33
|
-
cache_config:
|
33
|
+
cache_config: CacheConfig,
|
34
34
|
environment: Optional[str] = None,
|
35
35
|
debug: bool = False
|
36
|
-
) ->
|
36
|
+
) -> CacheConfig:
|
37
37
|
"""
|
38
38
|
Configure cache backend with environment-aware defaults.
|
39
39
|
|
@@ -50,7 +50,7 @@ class SmartDefaults:
|
|
50
50
|
"""
|
51
51
|
try:
|
52
52
|
# Create a copy to avoid modifying the original
|
53
|
-
config:
|
53
|
+
config: CacheConfig = cache_config.model_copy()
|
54
54
|
|
55
55
|
# Environment-specific adjustments
|
56
56
|
if environment == "testing":
|
@@ -168,8 +168,7 @@ class SmartDefaults:
|
|
168
168
|
domains: List[str],
|
169
169
|
environment: Optional[str] = None,
|
170
170
|
debug: bool = False,
|
171
|
-
ssl_redirect: Optional[bool] = None
|
172
|
-
cors_allow_headers: Optional[List[str]] = None
|
171
|
+
ssl_redirect: Optional[bool] = None
|
173
172
|
) -> Dict[str, Any]:
|
174
173
|
"""
|
175
174
|
Get security defaults based on environment and domains.
|
@@ -179,7 +178,6 @@ class SmartDefaults:
|
|
179
178
|
environment: Current environment
|
180
179
|
debug: Django DEBUG setting
|
181
180
|
ssl_redirect: Force SSL redirect on/off (None = auto based on domains)
|
182
|
-
cors_allow_headers: Custom CORS allowed headers
|
183
181
|
|
184
182
|
Returns:
|
185
183
|
Security settings dictionary
|
@@ -194,24 +192,6 @@ class SmartDefaults:
|
|
194
192
|
settings['CORS_ALLOW_ALL_ORIGINS'] = True
|
195
193
|
settings['CORS_ALLOW_CREDENTIALS'] = True
|
196
194
|
|
197
|
-
# Add CORS headers (custom or smart defaults)
|
198
|
-
if cors_allow_headers:
|
199
|
-
settings['CORS_ALLOW_HEADERS'] = cors_allow_headers
|
200
|
-
else:
|
201
|
-
# Smart defaults including X-API-Key
|
202
|
-
settings['CORS_ALLOW_HEADERS'] = [
|
203
|
-
"accept",
|
204
|
-
"accept-encoding",
|
205
|
-
"authorization",
|
206
|
-
"content-type",
|
207
|
-
"dnt",
|
208
|
-
"origin",
|
209
|
-
"user-agent",
|
210
|
-
"x-csrftoken",
|
211
|
-
"x-requested-with",
|
212
|
-
"x-api-key", # Add X-API-Key by default
|
213
|
-
]
|
214
|
-
|
215
195
|
# For development, add ALL domains to CSRF trusted origins
|
216
196
|
# This allows testing with production domains in dev environment
|
217
197
|
csrf_trusted_origins = []
|
@@ -261,24 +241,6 @@ class SmartDefaults:
|
|
261
241
|
settings['CORS_ALLOWED_ORIGINS'] = allowed_origins
|
262
242
|
settings['CORS_ALLOW_CREDENTIALS'] = True
|
263
243
|
|
264
|
-
# Add CORS headers (custom or smart defaults)
|
265
|
-
if cors_allow_headers:
|
266
|
-
settings['CORS_ALLOW_HEADERS'] = cors_allow_headers
|
267
|
-
else:
|
268
|
-
# Smart defaults including X-API-Key
|
269
|
-
settings['CORS_ALLOW_HEADERS'] = [
|
270
|
-
"accept",
|
271
|
-
"accept-encoding",
|
272
|
-
"authorization",
|
273
|
-
"content-type",
|
274
|
-
"dnt",
|
275
|
-
"origin",
|
276
|
-
"user-agent",
|
277
|
-
"x-csrftoken",
|
278
|
-
"x-requested-with",
|
279
|
-
"x-api-key", # Add X-API-Key by default
|
280
|
-
]
|
281
|
-
|
282
244
|
# Set CSRF trusted origins for HTTPS domains
|
283
245
|
if csrf_trusted_origins:
|
284
246
|
settings['CSRF_TRUSTED_ORIGINS'] = csrf_trusted_origins
|
@@ -442,7 +404,7 @@ class SmartDefaults:
|
|
442
404
|
}
|
443
405
|
|
444
406
|
elif environment == "development" or debug:
|
445
|
-
# Development: Console
|
407
|
+
# Development: Console logging with colors
|
446
408
|
return {
|
447
409
|
'version': 1,
|
448
410
|
'disable_existing_loggers': False,
|
@@ -451,23 +413,12 @@ class SmartDefaults:
|
|
451
413
|
'format': '{levelname} {asctime} {module} {process:d} {thread:d} {message}',
|
452
414
|
'style': '{',
|
453
415
|
},
|
454
|
-
'simple': {
|
455
|
-
'format': '{levelname} {asctime} {name} {message}',
|
456
|
-
'style': '{',
|
457
|
-
},
|
458
416
|
},
|
459
417
|
'handlers': {
|
460
418
|
'console': {
|
461
419
|
'class': 'logging.StreamHandler',
|
462
420
|
'formatter': 'verbose',
|
463
421
|
},
|
464
|
-
'file': {
|
465
|
-
'class': 'logging.handlers.RotatingFileHandler',
|
466
|
-
'filename': 'logs/django-cfg.log',
|
467
|
-
'maxBytes': 1024*1024*5, # 5MB
|
468
|
-
'backupCount': 3,
|
469
|
-
'formatter': 'simple',
|
470
|
-
},
|
471
422
|
},
|
472
423
|
'root': {
|
473
424
|
'handlers': ['console'],
|
@@ -479,11 +430,6 @@ class SmartDefaults:
|
|
479
430
|
'level': 'INFO',
|
480
431
|
'propagate': False,
|
481
432
|
},
|
482
|
-
'django_cfg': {
|
483
|
-
'handlers': ['console', 'file'],
|
484
|
-
'level': 'DEBUG',
|
485
|
-
'propagate': False,
|
486
|
-
},
|
487
433
|
},
|
488
434
|
}
|
489
435
|
|