django-cfg 1.1.81__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.
Files changed (246) hide show
  1. django_cfg/__init__.py +20 -448
  2. django_cfg/apps/accounts/README.md +3 -3
  3. django_cfg/apps/accounts/admin/__init__.py +0 -2
  4. django_cfg/apps/accounts/admin/activity.py +2 -9
  5. django_cfg/apps/accounts/admin/filters.py +0 -42
  6. django_cfg/apps/accounts/admin/inlines.py +8 -8
  7. django_cfg/apps/accounts/admin/otp.py +5 -5
  8. django_cfg/apps/accounts/admin/registration_source.py +1 -8
  9. django_cfg/apps/accounts/admin/user.py +12 -20
  10. django_cfg/apps/accounts/managers/user_manager.py +2 -129
  11. django_cfg/apps/accounts/migrations/0006_remove_twilioresponse_otp_secret_and_more.py +46 -0
  12. django_cfg/apps/accounts/models.py +3 -123
  13. django_cfg/apps/accounts/serializers/otp.py +40 -44
  14. django_cfg/apps/accounts/serializers/profile.py +0 -2
  15. django_cfg/apps/accounts/services/otp_service.py +98 -186
  16. django_cfg/apps/accounts/signals.py +25 -15
  17. django_cfg/apps/accounts/utils/auth_email_service.py +84 -0
  18. django_cfg/apps/accounts/views/otp.py +35 -36
  19. django_cfg/apps/agents/README.md +129 -0
  20. django_cfg/apps/agents/__init__.py +68 -0
  21. django_cfg/apps/agents/admin/__init__.py +17 -0
  22. django_cfg/apps/agents/admin/execution_admin.py +460 -0
  23. django_cfg/apps/agents/admin/registry_admin.py +360 -0
  24. django_cfg/apps/agents/admin/toolsets_admin.py +482 -0
  25. django_cfg/apps/agents/apps.py +29 -0
  26. django_cfg/apps/agents/core/__init__.py +20 -0
  27. django_cfg/apps/agents/core/agent.py +281 -0
  28. django_cfg/apps/agents/core/dependencies.py +154 -0
  29. django_cfg/apps/agents/core/exceptions.py +66 -0
  30. django_cfg/apps/agents/core/models.py +106 -0
  31. django_cfg/apps/agents/core/orchestrator.py +391 -0
  32. django_cfg/apps/agents/examples/__init__.py +3 -0
  33. django_cfg/apps/agents/examples/simple_example.py +161 -0
  34. django_cfg/apps/agents/integration/__init__.py +14 -0
  35. django_cfg/apps/agents/integration/middleware.py +80 -0
  36. django_cfg/apps/agents/integration/registry.py +345 -0
  37. django_cfg/apps/agents/integration/signals.py +50 -0
  38. django_cfg/apps/agents/management/__init__.py +3 -0
  39. django_cfg/apps/agents/management/commands/__init__.py +3 -0
  40. django_cfg/apps/agents/management/commands/create_agent.py +365 -0
  41. django_cfg/apps/agents/management/commands/orchestrator_status.py +191 -0
  42. django_cfg/apps/agents/managers/__init__.py +23 -0
  43. django_cfg/apps/agents/managers/execution.py +236 -0
  44. django_cfg/apps/agents/managers/registry.py +254 -0
  45. django_cfg/apps/agents/managers/toolsets.py +496 -0
  46. django_cfg/apps/agents/migrations/0001_initial.py +286 -0
  47. django_cfg/apps/agents/migrations/__init__.py +5 -0
  48. django_cfg/apps/agents/models/__init__.py +15 -0
  49. django_cfg/apps/agents/models/execution.py +215 -0
  50. django_cfg/apps/agents/models/registry.py +220 -0
  51. django_cfg/apps/agents/models/toolsets.py +305 -0
  52. django_cfg/apps/agents/patterns/__init__.py +24 -0
  53. django_cfg/apps/agents/patterns/content_agents.py +234 -0
  54. django_cfg/apps/agents/toolsets/__init__.py +15 -0
  55. django_cfg/apps/agents/toolsets/cache_toolset.py +285 -0
  56. django_cfg/apps/agents/toolsets/django_toolset.py +220 -0
  57. django_cfg/apps/agents/toolsets/file_toolset.py +324 -0
  58. django_cfg/apps/agents/toolsets/orm_toolset.py +319 -0
  59. django_cfg/apps/agents/urls.py +46 -0
  60. django_cfg/apps/knowbase/README.md +150 -0
  61. django_cfg/apps/knowbase/__init__.py +27 -0
  62. django_cfg/apps/knowbase/admin/__init__.py +23 -0
  63. django_cfg/apps/knowbase/admin/archive_admin.py +857 -0
  64. django_cfg/apps/knowbase/admin/chat_admin.py +386 -0
  65. django_cfg/apps/knowbase/admin/document_admin.py +650 -0
  66. django_cfg/apps/knowbase/admin/external_data_admin.py +685 -0
  67. django_cfg/apps/knowbase/apps.py +81 -0
  68. django_cfg/apps/knowbase/config/README.md +176 -0
  69. django_cfg/apps/knowbase/config/__init__.py +51 -0
  70. django_cfg/apps/knowbase/config/constance_fields.py +186 -0
  71. django_cfg/apps/knowbase/config/constance_settings.py +200 -0
  72. django_cfg/apps/knowbase/config/settings.py +444 -0
  73. django_cfg/apps/knowbase/examples/__init__.py +3 -0
  74. django_cfg/apps/knowbase/examples/external_data_usage.py +191 -0
  75. django_cfg/apps/knowbase/management/__init__.py +0 -0
  76. django_cfg/apps/knowbase/management/commands/__init__.py +0 -0
  77. django_cfg/apps/knowbase/management/commands/knowbase_stats.py +158 -0
  78. django_cfg/apps/knowbase/management/commands/setup_knowbase.py +59 -0
  79. django_cfg/apps/knowbase/managers/__init__.py +22 -0
  80. django_cfg/apps/knowbase/managers/archive.py +426 -0
  81. django_cfg/apps/knowbase/managers/base.py +32 -0
  82. django_cfg/apps/knowbase/managers/chat.py +141 -0
  83. django_cfg/apps/knowbase/managers/document.py +203 -0
  84. django_cfg/apps/knowbase/managers/external_data.py +471 -0
  85. django_cfg/apps/knowbase/migrations/0001_initial.py +427 -0
  86. django_cfg/apps/knowbase/migrations/0002_archiveitem_archiveitemchunk_documentarchive_and_more.py +434 -0
  87. django_cfg/apps/knowbase/migrations/__init__.py +5 -0
  88. django_cfg/apps/knowbase/mixins/__init__.py +15 -0
  89. django_cfg/apps/knowbase/mixins/config.py +108 -0
  90. django_cfg/apps/knowbase/mixins/creator.py +81 -0
  91. django_cfg/apps/knowbase/mixins/examples/vehicle_model_example.py +199 -0
  92. django_cfg/apps/knowbase/mixins/external_data_mixin.py +813 -0
  93. django_cfg/apps/knowbase/mixins/service.py +362 -0
  94. django_cfg/apps/knowbase/models/__init__.py +41 -0
  95. django_cfg/apps/knowbase/models/archive.py +599 -0
  96. django_cfg/apps/knowbase/models/base.py +58 -0
  97. django_cfg/apps/knowbase/models/chat.py +157 -0
  98. django_cfg/apps/knowbase/models/document.py +267 -0
  99. django_cfg/apps/knowbase/models/external_data.py +376 -0
  100. django_cfg/apps/knowbase/serializers/__init__.py +68 -0
  101. django_cfg/apps/knowbase/serializers/archive_serializers.py +386 -0
  102. django_cfg/apps/knowbase/serializers/chat_serializers.py +137 -0
  103. django_cfg/apps/knowbase/serializers/document_serializers.py +94 -0
  104. django_cfg/apps/knowbase/serializers/external_data_serializers.py +256 -0
  105. django_cfg/apps/knowbase/serializers/public_serializers.py +74 -0
  106. django_cfg/apps/knowbase/services/__init__.py +40 -0
  107. django_cfg/apps/knowbase/services/archive/__init__.py +42 -0
  108. django_cfg/apps/knowbase/services/archive/archive_service.py +541 -0
  109. django_cfg/apps/knowbase/services/archive/chunking_service.py +791 -0
  110. django_cfg/apps/knowbase/services/archive/exceptions.py +52 -0
  111. django_cfg/apps/knowbase/services/archive/extraction_service.py +508 -0
  112. django_cfg/apps/knowbase/services/archive/vectorization_service.py +362 -0
  113. django_cfg/apps/knowbase/services/base.py +53 -0
  114. django_cfg/apps/knowbase/services/chat_service.py +239 -0
  115. django_cfg/apps/knowbase/services/document_service.py +144 -0
  116. django_cfg/apps/knowbase/services/embedding/__init__.py +43 -0
  117. django_cfg/apps/knowbase/services/embedding/async_processor.py +244 -0
  118. django_cfg/apps/knowbase/services/embedding/batch_processor.py +250 -0
  119. django_cfg/apps/knowbase/services/embedding/batch_result.py +61 -0
  120. django_cfg/apps/knowbase/services/embedding/models.py +229 -0
  121. django_cfg/apps/knowbase/services/embedding/processors.py +148 -0
  122. django_cfg/apps/knowbase/services/embedding/utils.py +176 -0
  123. django_cfg/apps/knowbase/services/prompt_builder.py +191 -0
  124. django_cfg/apps/knowbase/services/search_service.py +293 -0
  125. django_cfg/apps/knowbase/signals/__init__.py +21 -0
  126. django_cfg/apps/knowbase/signals/archive_signals.py +211 -0
  127. django_cfg/apps/knowbase/signals/chat_signals.py +37 -0
  128. django_cfg/apps/knowbase/signals/document_signals.py +143 -0
  129. django_cfg/apps/knowbase/signals/external_data_signals.py +157 -0
  130. django_cfg/apps/knowbase/tasks/__init__.py +39 -0
  131. django_cfg/apps/knowbase/tasks/archive_tasks.py +316 -0
  132. django_cfg/apps/knowbase/tasks/document_processing.py +341 -0
  133. django_cfg/apps/knowbase/tasks/external_data_tasks.py +341 -0
  134. django_cfg/apps/knowbase/tasks/maintenance.py +195 -0
  135. django_cfg/apps/knowbase/urls.py +43 -0
  136. django_cfg/apps/knowbase/utils/__init__.py +12 -0
  137. django_cfg/apps/knowbase/utils/chunk_settings.py +261 -0
  138. django_cfg/apps/knowbase/utils/text_processing.py +375 -0
  139. django_cfg/apps/knowbase/utils/validation.py +99 -0
  140. django_cfg/apps/knowbase/views/__init__.py +28 -0
  141. django_cfg/apps/knowbase/views/archive_views.py +469 -0
  142. django_cfg/apps/knowbase/views/base.py +49 -0
  143. django_cfg/apps/knowbase/views/chat_views.py +181 -0
  144. django_cfg/apps/knowbase/views/document_views.py +183 -0
  145. django_cfg/apps/knowbase/views/public_views.py +129 -0
  146. django_cfg/apps/leads/admin.py +70 -0
  147. django_cfg/apps/newsletter/admin.py +234 -0
  148. django_cfg/apps/newsletter/admin_filters.py +124 -0
  149. django_cfg/apps/support/admin.py +196 -0
  150. django_cfg/apps/support/admin_filters.py +71 -0
  151. django_cfg/apps/support/templates/support/chat/ticket_chat.html +1 -1
  152. django_cfg/apps/urls.py +5 -4
  153. django_cfg/cli/README.md +1 -1
  154. django_cfg/cli/commands/create_project.py +2 -2
  155. django_cfg/cli/commands/info.py +1 -1
  156. django_cfg/config.py +44 -0
  157. django_cfg/core/config.py +29 -82
  158. django_cfg/core/environment.py +1 -1
  159. django_cfg/core/generation.py +19 -107
  160. django_cfg/{integration.py → core/integration.py} +18 -16
  161. django_cfg/core/validation.py +1 -1
  162. django_cfg/management/__init__.py +1 -1
  163. django_cfg/management/commands/__init__.py +1 -1
  164. django_cfg/management/commands/auto_generate.py +482 -0
  165. django_cfg/management/commands/migrator.py +19 -101
  166. django_cfg/management/commands/test_email.py +1 -1
  167. django_cfg/middleware/README.md +0 -158
  168. django_cfg/middleware/__init__.py +0 -2
  169. django_cfg/middleware/user_activity.py +3 -3
  170. django_cfg/models/api.py +145 -0
  171. django_cfg/models/base.py +287 -0
  172. django_cfg/models/cache.py +4 -4
  173. django_cfg/models/constance.py +25 -88
  174. django_cfg/models/database.py +9 -9
  175. django_cfg/models/drf.py +3 -36
  176. django_cfg/models/email.py +163 -0
  177. django_cfg/models/environment.py +276 -0
  178. django_cfg/models/limits.py +1 -1
  179. django_cfg/models/logging.py +366 -0
  180. django_cfg/models/revolution.py +41 -2
  181. django_cfg/models/security.py +125 -0
  182. django_cfg/models/services.py +1 -1
  183. django_cfg/modules/__init__.py +2 -56
  184. django_cfg/modules/base.py +78 -52
  185. django_cfg/modules/django_currency/service.py +2 -2
  186. django_cfg/modules/django_email.py +2 -2
  187. django_cfg/modules/django_health.py +267 -0
  188. django_cfg/modules/django_llm/llm/client.py +79 -17
  189. django_cfg/modules/django_llm/translator/translator.py +2 -2
  190. django_cfg/modules/django_logger.py +2 -2
  191. django_cfg/modules/django_ngrok.py +2 -2
  192. django_cfg/modules/django_tasks.py +68 -3
  193. django_cfg/modules/django_telegram.py +3 -3
  194. django_cfg/modules/django_twilio/sendgrid_service.py +2 -2
  195. django_cfg/modules/django_twilio/service.py +2 -2
  196. django_cfg/modules/django_twilio/simple_service.py +2 -2
  197. django_cfg/modules/django_twilio/templates/guide.md +266 -0
  198. django_cfg/modules/django_twilio/twilio_service.py +2 -2
  199. django_cfg/modules/django_unfold/__init__.py +69 -0
  200. django_cfg/modules/{unfold → django_unfold}/callbacks.py +23 -22
  201. django_cfg/modules/django_unfold/dashboard.py +278 -0
  202. django_cfg/modules/django_unfold/icons/README.md +145 -0
  203. django_cfg/modules/django_unfold/icons/__init__.py +12 -0
  204. django_cfg/modules/django_unfold/icons/constants.py +2851 -0
  205. django_cfg/modules/django_unfold/icons/generate_icons.py +486 -0
  206. django_cfg/modules/django_unfold/models/__init__.py +42 -0
  207. django_cfg/modules/django_unfold/models/config.py +601 -0
  208. django_cfg/modules/django_unfold/models/dashboard.py +206 -0
  209. django_cfg/modules/django_unfold/models/dropdown.py +40 -0
  210. django_cfg/modules/django_unfold/models/navigation.py +73 -0
  211. django_cfg/modules/django_unfold/models/tabs.py +25 -0
  212. django_cfg/modules/{unfold → django_unfold}/system_monitor.py +2 -2
  213. django_cfg/modules/django_unfold/utils.py +140 -0
  214. django_cfg/registry/__init__.py +23 -0
  215. django_cfg/registry/core.py +61 -0
  216. django_cfg/registry/exceptions.py +11 -0
  217. django_cfg/registry/modules.py +12 -0
  218. django_cfg/registry/services.py +26 -0
  219. django_cfg/registry/third_party.py +52 -0
  220. django_cfg/routing/__init__.py +19 -0
  221. django_cfg/routing/callbacks.py +198 -0
  222. django_cfg/routing/routers.py +48 -0
  223. django_cfg/templates/admin/layouts/dashboard_with_tabs.html +8 -9
  224. django_cfg/templatetags/__init__.py +0 -0
  225. django_cfg/templatetags/django_cfg.py +33 -0
  226. django_cfg/urls.py +33 -0
  227. django_cfg/utils/path_resolution.py +1 -1
  228. django_cfg/utils/smart_defaults.py +7 -61
  229. django_cfg/utils/toolkit.py +663 -0
  230. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/METADATA +83 -86
  231. django_cfg-1.2.0.dist-info/RECORD +441 -0
  232. django_cfg/apps/tasks/@docs/README.md +0 -195
  233. django_cfg/archive/django_sample.zip +0 -0
  234. django_cfg/models/unfold.py +0 -271
  235. django_cfg/modules/unfold/__init__.py +0 -29
  236. django_cfg/modules/unfold/dashboard.py +0 -318
  237. django_cfg/pyproject.toml +0 -370
  238. django_cfg/routers.py +0 -83
  239. django_cfg-1.1.81.dist-info/RECORD +0 -278
  240. /django_cfg/{exceptions.py → core/exceptions.py} +0 -0
  241. /django_cfg/modules/{unfold → django_unfold}/models.py +0 -0
  242. /django_cfg/modules/{unfold → django_unfold}/tailwind.py +0 -0
  243. /django_cfg/{version_check.py → utils/version_check.py} +0 -0
  244. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/WHEEL +0 -0
  245. {django_cfg-1.1.81.dist-info → django_cfg-1.2.0.dist-info}/entry_points.txt +0 -0
  246. {django_cfg-1.1.81.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
- Django Config Toolkit
433
- <span class="mx-2">•</span>
434
- <a href="/health/" class="text-primary-600 hover:text-primary-700">
435
- System Health
436
- </a>
437
- <span class="mx-2">•</span>
438
- <a href="/admin/" class="text-primary-600 hover:text-primary-700">
439
- Administration
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
@@ -13,7 +13,7 @@ import sys
13
13
  from typing import Optional, List, Dict, Any
14
14
  from pathlib import Path
15
15
 
16
- from django_cfg.exceptions import ConfigurationError
16
+ from django_cfg.core.exceptions import ConfigurationError
17
17
 
18
18
 
19
19
  class PathResolver:
@@ -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 CacheBackend
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: CacheBackend,
33
+ cache_config: CacheConfig,
34
34
  environment: Optional[str] = None,
35
35
  debug: bool = False
36
- ) -> CacheBackend:
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: CacheBackend = cache_config.model_copy()
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 and file logging
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