django-cfg 1.4.82__py3-none-any.whl → 1.4.84__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/centrifugo/serializers/channels.py +3 -0
- django_cfg/apps/centrifugo/serializers/publishes.py +2 -0
- django_cfg/apps/centrifugo/views/admin_api.py +1 -1
- django_cfg/apps/centrifugo/views/monitoring.py +116 -6
- django_cfg/apps/centrifugo/views/testing_api.py +1 -1
- django_cfg/apps/dashboard/__init__.py +8 -0
- django_cfg/apps/dashboard/api/__init__.py +27 -0
- django_cfg/apps/dashboard/api/serializers.py +165 -0
- django_cfg/apps/dashboard/api/viewsets.py +257 -0
- django_cfg/apps/dashboard/apps.py +23 -0
- django_cfg/apps/dashboard/services/__init__.py +11 -0
- django_cfg/apps/dashboard/services/statistics_service.py +235 -0
- django_cfg/apps/dashboard/services/system_health_service.py +280 -0
- django_cfg/apps/dashboard/urls.py +23 -0
- django_cfg/apps/frontend/JWT_AUTO_INJECTION.md +224 -0
- django_cfg/apps/frontend/views.py +121 -7
- django_cfg/apps/tasks/api/serializers.py +82 -0
- django_cfg/apps/tasks/api/views.py +571 -0
- django_cfg/apps/urls.py +2 -1
- django_cfg/core/builders/apps_builder.py +1 -0
- django_cfg/middleware/README.md +12 -0
- django_cfg/modules/django_client/core/generator/typescript/templates/fetchers/function.ts.jinja +1 -1
- django_cfg/modules/django_client/core/generator/typescript/templates/main_index.ts.jinja +7 -10
- django_cfg/modules/django_client/core/parser/openapi30.py +26 -1
- django_cfg/modules/django_client/core/parser/openapi31.py +26 -1
- django_cfg/pyproject.toml +1 -1
- django_cfg/static/frontend/admin/404.html +1 -1
- django_cfg/static/frontend/admin/500.html +1 -1
- django_cfg/static/frontend/admin/_next/static/-Zk0eDB7OJOEFrFyR5BwZ/_buildManifest.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{43076.55dd23b6cd68edb0.js → 20695.a7d37b6c40ad3f58.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{25033.d626f78bc99bc4a1.js → 25033.ee3e206d5a2877b6.js} +2 -2
- django_cfg/static/frontend/admin/_next/static/chunks/{25892.964150a58f94ce06.js → 25892.5cbed319f9226fdc.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{2d7a934f.dfef67639279d59d.js → 2d7a934f.329c61f23af1a7ec.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{30649.00c679812a56aee3.js → 30649.963cfb7268b5864a.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{30875.784491146c38dbcb.js → 30875.82c3741757b8aa32.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{32163.ab0ca435b3f26c04.js → 32163.109a03a7252f1508.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/43076-4be6a9794e9c3e8b.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{49978.fb8ba7ee52ffe666.js → 49978.db5a86a8eb233f35.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/50314-79c02212788f1ec7.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{50319.f786248384877960.js → 50319.fd78c7f7e3f1966e.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{52908.b690e323d8f8efdd.js → 52908.da5b850b0bc0970c.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{53710.80ca863525d137db.js → 53710.7176bbee6c7b78be.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{57982.251fed8d58adcf53.js → 57982.2c90b33b0934522a.js} +2 -2
- django_cfg/static/frontend/admin/_next/static/chunks/{60181.86e18057c4caaa97.js → 60181.c94d78d10eb5da37.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{60374.bde0ec1249aa79c6.js → 60374.5d80cfc45439b2b0.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{6884.7b1db804c88280ed.js → 6884.624d563508cf6db4.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{69436.9515b854cdf4b57a.js → 69436.be44021e3d7c99c7.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{70628.00cdd98f672e684f.js → 70628.58e8c38a66543d5e.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{73218.a826c2248612b37f.js → 73218.d712e7bd678e23a8.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{76334.64fbaa923d9ac293.js → 76334.f43f2d8b4bbf8dd6.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{7799.2b280f8ddf067d49.js → 7799.1575cc212bc750c7.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{80574.620a8a5b4eb91c25.js → 80574.92638dd7b9979664.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{81127.a0603c3394892d4e.js → 81127.3ead500eec887152.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/82296-a2c8d38f62224be5.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{8383.eb6188b22c453e14.js → 8383.e25a442df26b2e26.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{85833.35e6ca25ac32a7d2.js → 85833.b0dead4fbcbfdd1b.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{95365.fc9d7653a78839d0.js → 95365.2b430045fc2e5acf.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/{96424.0793b94836eb13a6.js → 96424.11d76570e9a94b85.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/404-c283223d1afd02a2.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/500-389d6d3e1f2f7fda.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/_app-f25bec36bbdc9625.js +272 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/_error-5291033275c26d09.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/index-d7bc30185f52cbca.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{cookies-24588bf5551f30df.js → cookies-b39c7f22c066e2c6.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{privacy-354dae34a4c4da59.js → privacy-5aedad0cf3a4f80f.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{security-0a5d7fa591ebb1ae.js → security-dbd854d0d5d483e2.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/legal/{terms-c3d80322f52dc112.js → terms-f3e1d2b9e5edf12f.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private/centrifugo-22532c65971225eb.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private/profile-e93a65e8e7d9022b.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private/ui-669e8f2a785beba2.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private-a8a9ba76f2c75354.js +1 -0
- django_cfg/static/frontend/admin/_next/static/chunks/{webpack-905bba30877f6490.js → webpack-92add5f95c66e349.js} +1 -1
- django_cfg/static/frontend/admin/_next/static/css/78d677ac1677c210.css +3 -0
- django_cfg/static/frontend/admin/auth.html +1 -1
- django_cfg/static/frontend/admin/index.html +1 -1
- django_cfg/static/frontend/admin/legal/cookies.html +1 -1
- django_cfg/static/frontend/admin/legal/privacy.html +1 -1
- django_cfg/static/frontend/admin/legal/security.html +1 -1
- django_cfg/static/frontend/admin/legal/terms.html +1 -1
- django_cfg/static/frontend/admin/private/centrifugo.html +1 -0
- django_cfg/static/frontend/admin/private/profile.html +1 -0
- django_cfg/static/frontend/admin/private/ui.html +1 -0
- django_cfg/static/frontend/admin/private.html +1 -1
- django_cfg/templates/admin/index.html +97 -63
- django_cfg/templates/admin_old/index.html +80 -0
- django_cfg/templatetags/django_cfg.py +57 -10
- {django_cfg-1.4.82.dist-info → django_cfg-1.4.84.dist-info}/METADATA +1 -1
- {django_cfg-1.4.82.dist-info → django_cfg-1.4.84.dist-info}/RECORD +142 -122
- django_cfg/static/frontend/admin/_next/static/chunks/pages/404-7cdad2942c3fb179.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/500-6cdb27b00678364f.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/_app-9c5ca2471de6b000.js +0 -272
- django_cfg/static/frontend/admin/_next/static/chunks/pages/_error-b8071a05cabe1c2d.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/index-bf88192a30e013a9.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/private-2f58633ddf63a5bc.js +0 -1
- django_cfg/static/frontend/admin/_next/static/chunks/pages/ui-73632f2d9c6b11ab.js +0 -1
- django_cfg/static/frontend/admin/_next/static/css/e201974f9a4d64e6.css +0 -3
- django_cfg/static/frontend/admin/_next/static/qEBrQJUidlI_maQ4xQnI0/_buildManifest.js +0 -1
- django_cfg/static/frontend/admin/ui.html +0 -92
- /django_cfg/static/frontend/admin/_next/static/{qEBrQJUidlI_maQ4xQnI0 → -Zk0eDB7OJOEFrFyR5BwZ}/_ssgManifest.js +0 -0
- /django_cfg/templates/{admin → admin_old}/components/action_grid.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/card.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/data_table.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/metric_card.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/modal.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/progress_bar.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/section_header.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/stat_item.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/stats_grid.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/status_badge.html +0 -0
- /django_cfg/templates/{admin → admin_old}/components/user_avatar.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/change_list.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/includes/default_value.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/includes/fieldset_header.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/includes/results_list.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/includes/setting_row.html +0 -0
- /django_cfg/templates/{admin → admin_old}/constance/includes/table_headers.html +0 -0
- /django_cfg/templates/{admin → admin_old}/examples/component_class_example.html +0 -0
- /django_cfg/templates/{admin → admin_old}/import_export/change_list_export.html +0 -0
- /django_cfg/templates/{admin → admin_old}/import_export/change_list_import.html +0 -0
- /django_cfg/templates/{admin → admin_old}/import_export/change_list_import_export.html +0 -0
- /django_cfg/templates/{admin → admin_old}/index_new.html +0 -0
- /django_cfg/templates/{admin → admin_old}/layouts/base_dashboard.html +0 -0
- /django_cfg/templates/{admin → admin_old}/layouts/dashboard_with_tabs.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/commands_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/documentation_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/overview_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/stats_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/system_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/sections/widgets_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/activity_tracker.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/charts_section.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/django_commands.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/quick_actions.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/recent_activity_improved.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/recent_users_table.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/stats_cards.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/stats_tiles.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/system_health.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/system_metrics.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/components/user_permissions.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/app_stats_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/commands_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/documentation_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/overview_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/stats_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/users_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/tabs/widgets_tab.html +0 -0
- /django_cfg/templates/{admin → admin_old}/snippets/zones/zones_table.html +0 -0
- {django_cfg-1.4.82.dist-info → django_cfg-1.4.84.dist-info}/WHEEL +0 -0
- {django_cfg-1.4.82.dist-info → django_cfg-1.4.84.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.4.82.dist-info → django_cfg-1.4.84.dist-info}/licenses/LICENSE +0 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{% extends 'admin/layouts/dashboard_with_tabs.html' %}
|
|
2
|
+
|
|
3
|
+
{% load unfold %}
|
|
4
|
+
|
|
5
|
+
{% block overview_tab %}
|
|
6
|
+
{% if overview_section %}
|
|
7
|
+
{{ overview_section|safe }}
|
|
8
|
+
{% else %}
|
|
9
|
+
{% include 'admin/snippets/tabs/overview_tab.html' %}
|
|
10
|
+
{% endif %}
|
|
11
|
+
{% endblock %}
|
|
12
|
+
|
|
13
|
+
{% block zones_tab %}
|
|
14
|
+
{% if zones_section %}
|
|
15
|
+
{{ zones_section|safe }}
|
|
16
|
+
{% else %}
|
|
17
|
+
{% include 'admin/snippets/zones/zones_table.html' %}
|
|
18
|
+
{% endif %}
|
|
19
|
+
{% endblock %}
|
|
20
|
+
|
|
21
|
+
{% block users_tab %}
|
|
22
|
+
{% if users_section %}
|
|
23
|
+
{{ users_section|safe }}
|
|
24
|
+
{% else %}
|
|
25
|
+
{% include 'admin/snippets/tabs/users_tab.html' %}
|
|
26
|
+
{% endif %}
|
|
27
|
+
{% endblock %}
|
|
28
|
+
|
|
29
|
+
{% block system_tab %}
|
|
30
|
+
{% if system_section %}
|
|
31
|
+
{{ system_section|safe }}
|
|
32
|
+
{% else %}
|
|
33
|
+
<div class="space-y-8">
|
|
34
|
+
<h2 class="text-xl font-semibold text-font-important-light dark:text-font-important-dark mb-4">
|
|
35
|
+
System Management
|
|
36
|
+
</h2>
|
|
37
|
+
|
|
38
|
+
<!-- System Health -->
|
|
39
|
+
{% include 'admin/snippets/components/system_health.html' %}
|
|
40
|
+
|
|
41
|
+
<!-- System Metrics -->
|
|
42
|
+
{% include 'admin/snippets/components/system_metrics.html' %}
|
|
43
|
+
|
|
44
|
+
<!-- Activity Tracker -->
|
|
45
|
+
{% include 'admin/snippets/components/activity_tracker.html' %}
|
|
46
|
+
</div>
|
|
47
|
+
{% endif %}
|
|
48
|
+
{% endblock %}
|
|
49
|
+
|
|
50
|
+
{% block stats_tab %}
|
|
51
|
+
{% if stats_section %}
|
|
52
|
+
{{ stats_section|safe }}
|
|
53
|
+
{% else %}
|
|
54
|
+
{% include 'admin/snippets/tabs/stats_tab.html' %}
|
|
55
|
+
{% endif %}
|
|
56
|
+
{% endblock %}
|
|
57
|
+
|
|
58
|
+
{% block app_stats_tab %}
|
|
59
|
+
{% if app_stats_section %}
|
|
60
|
+
{{ app_stats_section|safe }}
|
|
61
|
+
{% else %}
|
|
62
|
+
{% include 'admin/snippets/tabs/app_stats_tab.html' with stats_groups=stats_groups %}
|
|
63
|
+
{% endif %}
|
|
64
|
+
{% endblock %}
|
|
65
|
+
|
|
66
|
+
{% block commands_tab %}
|
|
67
|
+
{% if commands_section %}
|
|
68
|
+
{{ commands_section|safe }}
|
|
69
|
+
{% else %}
|
|
70
|
+
{% include 'admin/snippets/tabs/commands_tab.html' %}
|
|
71
|
+
{% endif %}
|
|
72
|
+
{% endblock %}
|
|
73
|
+
|
|
74
|
+
{% block widgets_tab %}
|
|
75
|
+
{% if widgets_section %}
|
|
76
|
+
{{ widgets_section|safe }}
|
|
77
|
+
{% else %}
|
|
78
|
+
{% include 'admin/snippets/tabs/widgets_tab.html' %}
|
|
79
|
+
{% endif %}
|
|
80
|
+
{% endblock %}
|
|
@@ -5,11 +5,8 @@ Provides template tags for accessing django-cfg configuration constants.
|
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from django import template
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
from rest_framework_simplejwt.tokens import RefreshToken
|
|
11
|
-
except ImportError:
|
|
12
|
-
RefreshToken = None
|
|
8
|
+
from django.utils.safestring import mark_safe
|
|
9
|
+
from rest_framework_simplejwt.tokens import RefreshToken
|
|
13
10
|
|
|
14
11
|
register = template.Library()
|
|
15
12
|
|
|
@@ -75,15 +72,65 @@ def user_jwt_token(context):
|
|
|
75
72
|
window.USER_JWT_TOKEN = '{% user_jwt_token %}';
|
|
76
73
|
</script>
|
|
77
74
|
"""
|
|
78
|
-
|
|
75
|
+
request = context.get('request')
|
|
76
|
+
if not request or not request.user or not request.user.is_authenticated:
|
|
79
77
|
return ''
|
|
80
78
|
|
|
79
|
+
refresh = RefreshToken.for_user(request.user)
|
|
80
|
+
return str(refresh.access_token)
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
@register.simple_tag(takes_context=True)
|
|
84
|
+
def user_jwt_refresh_token(context):
|
|
85
|
+
"""
|
|
86
|
+
Generate JWT refresh token for the current authenticated user.
|
|
87
|
+
|
|
88
|
+
Returns JWT refresh token that can be used to obtain new access tokens.
|
|
89
|
+
|
|
90
|
+
Usage in template:
|
|
91
|
+
{% load django_cfg %}
|
|
92
|
+
<script>
|
|
93
|
+
window.USER_JWT_REFRESH_TOKEN = '{% user_jwt_refresh_token %}';
|
|
94
|
+
</script>
|
|
95
|
+
"""
|
|
81
96
|
request = context.get('request')
|
|
82
97
|
if not request or not request.user or not request.user.is_authenticated:
|
|
83
98
|
return ''
|
|
84
99
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
100
|
+
refresh = RefreshToken.for_user(request.user)
|
|
101
|
+
return str(refresh)
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@register.simple_tag(takes_context=True)
|
|
105
|
+
def inject_jwt_tokens_script(context):
|
|
106
|
+
"""
|
|
107
|
+
Generate complete script tag that injects JWT tokens into localStorage.
|
|
108
|
+
|
|
109
|
+
Automatically stores auth_token and refresh_token in localStorage
|
|
110
|
+
for the current authenticated user.
|
|
111
|
+
|
|
112
|
+
Usage in template (usually in <head> or before </body>):
|
|
113
|
+
{% load django_cfg %}
|
|
114
|
+
{% inject_jwt_tokens_script %}
|
|
115
|
+
"""
|
|
116
|
+
request = context.get('request')
|
|
117
|
+
if not request or not request.user or not request.user.is_authenticated:
|
|
89
118
|
return ''
|
|
119
|
+
|
|
120
|
+
refresh = RefreshToken.for_user(request.user)
|
|
121
|
+
access_token = str(refresh.access_token)
|
|
122
|
+
refresh_token = str(refresh)
|
|
123
|
+
|
|
124
|
+
script = f"""<script>
|
|
125
|
+
(function() {{
|
|
126
|
+
try {{
|
|
127
|
+
// Store JWT tokens in localStorage for Next.js app
|
|
128
|
+
localStorage.setItem('auth_token', '{access_token}');
|
|
129
|
+
localStorage.setItem('refresh_token', '{refresh_token}');
|
|
130
|
+
console.log('JWT tokens injected successfully');
|
|
131
|
+
}} catch (e) {{
|
|
132
|
+
console.error('Failed to inject JWT tokens:', e);
|
|
133
|
+
}}
|
|
134
|
+
}})();
|
|
135
|
+
</script>"""
|
|
136
|
+
return mark_safe(script)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: django-cfg
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.84
|
|
4
4
|
Summary: Django AI framework with built-in agents, type-safe Pydantic v2 configuration, and 8 enterprise apps. Replace settings.py, validate at startup, 90% less code. Production-ready AI workflows for Django.
|
|
5
5
|
Project-URL: Homepage, https://djangocfg.com
|
|
6
6
|
Project-URL: Documentation, https://djangocfg.com
|