django-cfg 1.1.73__tar.gz → 1.1.75__tar.gz
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-1.1.73 → django_cfg-1.1.75}/PKG-INFO +44 -7
- {django_cfg-1.1.73 → django_cfg-1.1.75}/README.md +43 -6
- {django_cfg-1.1.73 → django_cfg-1.1.75}/pyproject.toml +1 -1
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/__init__.py +1 -1
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/managers/user_manager.py +2 -2
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/core/config.py +1 -0
- django_cfg-1.1.75/src/django_cfg/management/commands/migrate_all.py +117 -0
- django_cfg-1.1.75/src/django_cfg/middleware/README.md +318 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/middleware/__init__.py +2 -0
- django_cfg-1.1.75/src/django_cfg/middleware/public_endpoints.py +182 -0
- django_cfg-1.1.73/src/django_cfg/middleware/README.md +0 -160
- {django_cfg-1.1.73 → django_cfg-1.1.75}/.gitignore +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/LICENSE +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/MANIFEST.in +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/requirements-dev.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/requirements-test.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/requirements.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/activity.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/filters.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/group.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/inlines.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/otp.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/registration_source.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/resources.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/twilio_response.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/admin/user.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/management/commands/test_otp.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/managers/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/0002_add_phone_otp_clean.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/0003_twilioresponse.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/0004_delete_twilioresponse.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/0005_twilioresponse.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/migrations/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/serializers/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/serializers/otp.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/serializers/profile.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/serializers/webhook.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/services/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/services/activity_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/services/otp_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/signals.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/base_email.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/base_email.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/otp_email.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/otp_email.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/welcome_email.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/templates/emails/welcome_email.txt +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/utils/notifications.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/views/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/views/otp.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/views/profile.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/views/webhook.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/commands/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/commands/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/commands/views.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/health/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/health/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/api/health/views.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/admin/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/admin/leads_admin.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/admin/resources.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/migrations/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/serializers.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/signals.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/tests.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/leads/views.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/admin/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/admin/filters.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/admin/newsletter_admin.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/admin/resources.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/management/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/management/commands/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/management/commands/test_newsletter.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/managers/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/managers/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/migrations/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/serializers.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/services/email_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/signals.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/utils/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/campaigns.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/emails.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/newsletters.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/subscriptions.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/newsletter/views/tracking.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/admin/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/admin/filters.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/admin/resources.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/admin/support_admin.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/managers/message_manager.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/managers/ticket_manager.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/migrations/0001_initial.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/migrations/0002_alter_message_ticket.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/migrations/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/serializers.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/signals.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/templates/support/chat/access_denied.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/templates/support/chat/ticket_chat.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/utils/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/utils/support_email_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/views/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/views/admin.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/views/api.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/support/views/chat.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/admin.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/serializers.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/css/dashboard.css +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/api.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/modals.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/static/tasks/js/theme.js +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/base.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/management_actions.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/status_cards.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/tasks/views.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/archive/django_sample.zip +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/commands/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/commands/create_project.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/commands/info.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/main.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/cli/utils.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/core/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/core/environment.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/core/generation.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/core/validation.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/exceptions.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/integration.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/check_settings.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/clear_constance.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/create_token.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/generate.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/list_urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/migrator.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/rundramatiq.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/runserver_ngrok.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/script.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/show_config.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/show_urls.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/superuser.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/task_clear.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/task_status.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/test_email.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/test_telegram.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/test_twilio.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/tree.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/management/commands/validate_config.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/middleware/user_activity.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/cache.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/constance.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/database.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/drf.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/jwt.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/limits.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/ngrok.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/revolution.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/services.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/tasks.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/models/unfold.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/base.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_currency/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_currency/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_currency/cache.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_currency/converter.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_currency/service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_email.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/example.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/cache.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/client.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/costs.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/extractor.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/models_cache.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/llm/tokenizer.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/translator/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/translator/cache.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_llm/translator/translator.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_logger.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_ngrok.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_tasks.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_telegram.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/README.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/exceptions.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/sendgrid_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/simple_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/templates/guide.md +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/templates/sendgrid_otp_email.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/templates/sendgrid_test_data.json +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/django_twilio/twilio_service.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/dramatiq_setup.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/logger.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/callbacks.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/dashboard.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/models.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/system_monitor.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/modules/unfold/tailwind.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/pyproject.toml +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/routers.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/index.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/layouts/dashboard_with_tabs.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/activity_tracker.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/charts_section.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/django_commands.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/quick_actions.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/recent_activity.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/recent_users_table.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/stats_cards.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/stats_tiles.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/system_health.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/system_metrics.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/components/user_permissions.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/tabs/app_stats_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/tabs/commands_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/tabs/overview_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/tabs/stats_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/tabs/users_tab.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/admin/snippets/zones/zones_table.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/templates/emails/base_email.html +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/utils/__init__.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/utils/path_resolution.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/utils/smart_defaults.py +0 -0
- {django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/version_check.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: django-cfg
|
3
|
-
Version: 1.1.
|
3
|
+
Version: 1.1.75
|
4
4
|
Summary: 🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience
|
5
5
|
Project-URL: Homepage, https://github.com/markolofsen/django-cfg
|
6
6
|
Project-URL: Documentation, https://django-cfg.readthedocs.io
|
@@ -552,31 +552,68 @@ def queue_document_processing(sender, instance, created, **kwargs):
|
|
552
552
|
|
553
553
|
Django-CFG includes powerful management commands for development and operations:
|
554
554
|
|
555
|
+
### 🗄️ Database & Migration Commands
|
556
|
+
| Command | Description | Example |
|
557
|
+
|---------|-------------|---------|
|
558
|
+
| **`migrator`** | Interactive database migration tool with multi-DB support | `python manage.py migrator --auto` |
|
559
|
+
| **`migrate_all`** | Simple migration command for all databases (production-ready) | `python manage.py migrate_all --dry-run` |
|
560
|
+
|
561
|
+
**Migration Command Details:**
|
562
|
+
- **`migrator`** - Full-featured migration tool with interactive menu, database status, and diagnostics
|
563
|
+
- `python manage.py migrator` - Interactive menu with all options
|
564
|
+
- `python manage.py migrator --auto` - Automatic migration of all databases
|
565
|
+
- `python manage.py migrator --database vehicles` - Migrate specific database only
|
566
|
+
- `python manage.py migrator --app vehicles_data` - Migrate specific app across all databases
|
567
|
+
- **`migrate_all`** - Simplified migration tool optimized for production and CI/CD
|
568
|
+
- `python manage.py migrate_all` - Migrate all databases automatically
|
569
|
+
- `python manage.py migrate_all --dry-run` - Show what would be migrated without executing
|
570
|
+
- `python manage.py migrate_all --skip-makemigrations` - Skip makemigrations step
|
571
|
+
|
572
|
+
### 🔧 Configuration & Validation Commands
|
555
573
|
| Command | Description | Example |
|
556
574
|
|---------|-------------|---------|
|
557
575
|
| **`check_settings`** | Validate configuration and settings | `python manage.py check_settings` |
|
576
|
+
| **`show_config`** | Display current configuration | `python manage.py show_config --format yaml` |
|
577
|
+
| **`validate_config`** | Deep validation of all settings | `python manage.py validate_config --strict` |
|
578
|
+
| **`tree`** | Display Django project structure | `python manage.py tree --depth 3 --include-docs` |
|
579
|
+
|
580
|
+
### 🚀 API & Development Commands
|
581
|
+
| Command | Description | Example |
|
582
|
+
|---------|-------------|---------|
|
558
583
|
| **`create_token`** | Generate API tokens and keys | `python manage.py create_token --user admin` |
|
559
584
|
| **`generate`** | Generate API clients and documentation | `python manage.py generate --zone client` |
|
560
|
-
| **`migrator`** | Smart database migrations with routing | `python manage.py migrator --apps blog,shop` |
|
561
|
-
| **`script`** | Run custom scripts with Django context | `python manage.py script my_script.py` |
|
562
|
-
| **`show_config`** | Display current configuration | `python manage.py show_config --format yaml` |
|
563
585
|
| **`show_urls`** | Display all URL patterns | `python manage.py show_urls --zone client` |
|
586
|
+
| **`script`** | Run custom scripts with Django context | `python manage.py script my_script.py` |
|
587
|
+
| **`runserver_ngrok`** | Run development server with ngrok tunnel | `python manage.py runserver_ngrok --domain custom` |
|
588
|
+
|
589
|
+
### 👤 User & Authentication Commands
|
590
|
+
| Command | Description | Example |
|
591
|
+
|---------|-------------|---------|
|
564
592
|
| **`superuser`** | Create superuser with smart defaults | `python manage.py superuser --email admin@example.com` |
|
593
|
+
|
594
|
+
### 📧 Communication & Integration Commands
|
595
|
+
| Command | Description | Example |
|
596
|
+
|---------|-------------|---------|
|
565
597
|
| **`test_email`** | Test email configuration | `python manage.py test_email --to test@example.com` |
|
566
598
|
| **`test_telegram`** | Test Telegram bot integration | `python manage.py test_telegram --chat_id 123` |
|
567
599
|
| **`test_twilio`** | Test Twilio SMS and WhatsApp integration | `python manage.py test_twilio` |
|
568
600
|
| **`translate_content`** | Translate JSON with LLM and smart caching | `python manage.py translate_content --target-lang es` |
|
601
|
+
|
602
|
+
### 🎫 Built-in Module Commands
|
603
|
+
| Command | Description | Example |
|
604
|
+
|---------|-------------|---------|
|
569
605
|
| **`support_stats`** | Display support ticket statistics | `python manage.py support_stats --format json` |
|
570
606
|
| **`test_newsletter`** | Test newsletter sending functionality | `python manage.py test_newsletter --email test@example.com` |
|
571
607
|
| **`newsletter_stats`** | Display newsletter campaign statistics | `python manage.py newsletter_stats --format json` |
|
572
608
|
| **`leads_stats`** | Display lead conversion statistics | `python manage.py leads_stats --format json` |
|
573
|
-
|
609
|
+
|
610
|
+
### 🔄 Background Task Commands
|
611
|
+
| Command | Description | Example |
|
612
|
+
|---------|-------------|---------|
|
574
613
|
| **`rundramatiq`** | Run Dramatiq background task workers | `python manage.py rundramatiq --processes 4` |
|
575
614
|
| **`task_status`** | Show Dramatiq task status and queues | `python manage.py task_status --queue high` |
|
576
615
|
| **`task_clear`** | Clear Dramatiq queues | `python manage.py task_clear --queue default` |
|
577
616
|
| **`test_tasks`** | Test Dramatiq task processing pipeline | `python manage.py test_tasks --document-id 123` |
|
578
|
-
| **`tree`** | Display Django project structure | `python manage.py tree --depth 3 --include-docs` |
|
579
|
-
| **`validate_config`** | Deep validation of all settings | `python manage.py validate_config --strict` |
|
580
617
|
|
581
618
|
---
|
582
619
|
|
@@ -425,31 +425,68 @@ def queue_document_processing(sender, instance, created, **kwargs):
|
|
425
425
|
|
426
426
|
Django-CFG includes powerful management commands for development and operations:
|
427
427
|
|
428
|
+
### 🗄️ Database & Migration Commands
|
429
|
+
| Command | Description | Example |
|
430
|
+
|---------|-------------|---------|
|
431
|
+
| **`migrator`** | Interactive database migration tool with multi-DB support | `python manage.py migrator --auto` |
|
432
|
+
| **`migrate_all`** | Simple migration command for all databases (production-ready) | `python manage.py migrate_all --dry-run` |
|
433
|
+
|
434
|
+
**Migration Command Details:**
|
435
|
+
- **`migrator`** - Full-featured migration tool with interactive menu, database status, and diagnostics
|
436
|
+
- `python manage.py migrator` - Interactive menu with all options
|
437
|
+
- `python manage.py migrator --auto` - Automatic migration of all databases
|
438
|
+
- `python manage.py migrator --database vehicles` - Migrate specific database only
|
439
|
+
- `python manage.py migrator --app vehicles_data` - Migrate specific app across all databases
|
440
|
+
- **`migrate_all`** - Simplified migration tool optimized for production and CI/CD
|
441
|
+
- `python manage.py migrate_all` - Migrate all databases automatically
|
442
|
+
- `python manage.py migrate_all --dry-run` - Show what would be migrated without executing
|
443
|
+
- `python manage.py migrate_all --skip-makemigrations` - Skip makemigrations step
|
444
|
+
|
445
|
+
### 🔧 Configuration & Validation Commands
|
428
446
|
| Command | Description | Example |
|
429
447
|
|---------|-------------|---------|
|
430
448
|
| **`check_settings`** | Validate configuration and settings | `python manage.py check_settings` |
|
449
|
+
| **`show_config`** | Display current configuration | `python manage.py show_config --format yaml` |
|
450
|
+
| **`validate_config`** | Deep validation of all settings | `python manage.py validate_config --strict` |
|
451
|
+
| **`tree`** | Display Django project structure | `python manage.py tree --depth 3 --include-docs` |
|
452
|
+
|
453
|
+
### 🚀 API & Development Commands
|
454
|
+
| Command | Description | Example |
|
455
|
+
|---------|-------------|---------|
|
431
456
|
| **`create_token`** | Generate API tokens and keys | `python manage.py create_token --user admin` |
|
432
457
|
| **`generate`** | Generate API clients and documentation | `python manage.py generate --zone client` |
|
433
|
-
| **`migrator`** | Smart database migrations with routing | `python manage.py migrator --apps blog,shop` |
|
434
|
-
| **`script`** | Run custom scripts with Django context | `python manage.py script my_script.py` |
|
435
|
-
| **`show_config`** | Display current configuration | `python manage.py show_config --format yaml` |
|
436
458
|
| **`show_urls`** | Display all URL patterns | `python manage.py show_urls --zone client` |
|
459
|
+
| **`script`** | Run custom scripts with Django context | `python manage.py script my_script.py` |
|
460
|
+
| **`runserver_ngrok`** | Run development server with ngrok tunnel | `python manage.py runserver_ngrok --domain custom` |
|
461
|
+
|
462
|
+
### 👤 User & Authentication Commands
|
463
|
+
| Command | Description | Example |
|
464
|
+
|---------|-------------|---------|
|
437
465
|
| **`superuser`** | Create superuser with smart defaults | `python manage.py superuser --email admin@example.com` |
|
466
|
+
|
467
|
+
### 📧 Communication & Integration Commands
|
468
|
+
| Command | Description | Example |
|
469
|
+
|---------|-------------|---------|
|
438
470
|
| **`test_email`** | Test email configuration | `python manage.py test_email --to test@example.com` |
|
439
471
|
| **`test_telegram`** | Test Telegram bot integration | `python manage.py test_telegram --chat_id 123` |
|
440
472
|
| **`test_twilio`** | Test Twilio SMS and WhatsApp integration | `python manage.py test_twilio` |
|
441
473
|
| **`translate_content`** | Translate JSON with LLM and smart caching | `python manage.py translate_content --target-lang es` |
|
474
|
+
|
475
|
+
### 🎫 Built-in Module Commands
|
476
|
+
| Command | Description | Example |
|
477
|
+
|---------|-------------|---------|
|
442
478
|
| **`support_stats`** | Display support ticket statistics | `python manage.py support_stats --format json` |
|
443
479
|
| **`test_newsletter`** | Test newsletter sending functionality | `python manage.py test_newsletter --email test@example.com` |
|
444
480
|
| **`newsletter_stats`** | Display newsletter campaign statistics | `python manage.py newsletter_stats --format json` |
|
445
481
|
| **`leads_stats`** | Display lead conversion statistics | `python manage.py leads_stats --format json` |
|
446
|
-
|
482
|
+
|
483
|
+
### 🔄 Background Task Commands
|
484
|
+
| Command | Description | Example |
|
485
|
+
|---------|-------------|---------|
|
447
486
|
| **`rundramatiq`** | Run Dramatiq background task workers | `python manage.py rundramatiq --processes 4` |
|
448
487
|
| **`task_status`** | Show Dramatiq task status and queues | `python manage.py task_status --queue high` |
|
449
488
|
| **`task_clear`** | Clear Dramatiq queues | `python manage.py task_clear --queue default` |
|
450
489
|
| **`test_tasks`** | Test Dramatiq task processing pipeline | `python manage.py test_tasks --document-id 123` |
|
451
|
-
| **`tree`** | Display Django project structure | `python manage.py tree --depth 3 --include-docs` |
|
452
|
-
| **`validate_config`** | Deep validation of all settings | `python manage.py validate_config --strict` |
|
453
490
|
|
454
491
|
---
|
455
492
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "django-cfg"
|
7
|
-
version = "1.1.
|
7
|
+
version = "1.1.75"
|
8
8
|
description = "🚀 Production-ready Django configuration framework with type-safe settings, smart automation, and modern developer experience"
|
9
9
|
readme = "README.md"
|
10
10
|
license = {text = "MIT"}
|
@@ -38,7 +38,7 @@ default_app_config = "django_cfg.apps.DjangoCfgConfig"
|
|
38
38
|
from typing import TYPE_CHECKING
|
39
39
|
|
40
40
|
# Version information
|
41
|
-
__version__ = "1.1.
|
41
|
+
__version__ = "1.1.75"
|
42
42
|
__author__ = "Unrealos Team"
|
43
43
|
__email__ = "info@unrealos.com"
|
44
44
|
__license__ = "MIT"
|
{django_cfg-1.1.73 → django_cfg-1.1.75}/src/django_cfg/apps/accounts/managers/user_manager.py
RENAMED
@@ -83,8 +83,8 @@ class UserManager(UserManager):
|
|
83
83
|
f"Attempting to get_or_create user with email: {email}, username: {username}"
|
84
84
|
)
|
85
85
|
|
86
|
-
# Create or get user using self
|
87
|
-
user, created = self.
|
86
|
+
# Create or get user using self (the manager)
|
87
|
+
user, created = self.get_or_create(
|
88
88
|
email=email, defaults=defaults
|
89
89
|
)
|
90
90
|
|
@@ -633,6 +633,7 @@ class DjangoConfig(BaseModel):
|
|
633
633
|
"django.contrib.sessions.middleware.SessionMiddleware",
|
634
634
|
"django.middleware.common.CommonMiddleware",
|
635
635
|
"django.middleware.csrf.CsrfViewMiddleware",
|
636
|
+
"django_cfg.middleware.PublicEndpointsMiddleware", # Handle invalid JWT tokens on public endpoints
|
636
637
|
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
637
638
|
"django.contrib.messages.middleware.MessageMiddleware",
|
638
639
|
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
@@ -0,0 +1,117 @@
|
|
1
|
+
"""
|
2
|
+
Simple Migration Command for Django Config Toolkit
|
3
|
+
Migrate all databases based on django-cfg configuration.
|
4
|
+
"""
|
5
|
+
|
6
|
+
from django.core.management.base import BaseCommand
|
7
|
+
from django.core.management import call_command
|
8
|
+
from django.apps import apps
|
9
|
+
|
10
|
+
from django_cfg.core.config import get_current_config
|
11
|
+
|
12
|
+
|
13
|
+
class Command(BaseCommand):
|
14
|
+
help = "Migrate all databases based on django-cfg configuration"
|
15
|
+
|
16
|
+
def add_arguments(self, parser):
|
17
|
+
parser.add_argument(
|
18
|
+
"--dry-run",
|
19
|
+
action="store_true",
|
20
|
+
help="Show what would be migrated without executing"
|
21
|
+
)
|
22
|
+
parser.add_argument(
|
23
|
+
"--skip-makemigrations",
|
24
|
+
action="store_true",
|
25
|
+
help="Skip makemigrations step"
|
26
|
+
)
|
27
|
+
|
28
|
+
def handle(self, *args, **options):
|
29
|
+
"""Run migrations for all configured databases."""
|
30
|
+
dry_run = options.get("dry_run", False)
|
31
|
+
skip_makemigrations = options.get("skip_makemigrations", False)
|
32
|
+
|
33
|
+
if dry_run:
|
34
|
+
self.stdout.write(self.style.WARNING("🔍 DRY RUN - No changes will be made"))
|
35
|
+
|
36
|
+
self.stdout.write(self.style.SUCCESS("🚀 Migrating all databases..."))
|
37
|
+
|
38
|
+
# Step 1: Create migrations if needed
|
39
|
+
if not skip_makemigrations:
|
40
|
+
self.stdout.write("📝 Creating migrations...")
|
41
|
+
if not dry_run:
|
42
|
+
call_command("makemigrations", verbosity=1)
|
43
|
+
else:
|
44
|
+
self.stdout.write(" Would run: makemigrations")
|
45
|
+
|
46
|
+
# Step 2: Get database configuration
|
47
|
+
try:
|
48
|
+
config = get_current_config()
|
49
|
+
if not config or not hasattr(config, 'databases'):
|
50
|
+
self.stdout.write(self.style.ERROR("❌ No django-cfg configuration found"))
|
51
|
+
return
|
52
|
+
except Exception as e:
|
53
|
+
self.stdout.write(self.style.ERROR(f"❌ Error loading configuration: {e}"))
|
54
|
+
return
|
55
|
+
|
56
|
+
# Step 3: Migrate each database
|
57
|
+
for db_name, db_config in config.databases.items():
|
58
|
+
self.stdout.write(f"\n🔄 Migrating database: {db_name}")
|
59
|
+
|
60
|
+
if hasattr(db_config, 'apps') and db_config.apps:
|
61
|
+
# Migrate specific apps for this database
|
62
|
+
for app_path in db_config.apps:
|
63
|
+
app_label = self._get_app_label(app_path)
|
64
|
+
if app_label:
|
65
|
+
self.stdout.write(f" 📦 Migrating {app_label}...")
|
66
|
+
if not dry_run:
|
67
|
+
try:
|
68
|
+
call_command("migrate", app_label, database=db_name, verbosity=1)
|
69
|
+
except Exception as e:
|
70
|
+
self.stdout.write(self.style.WARNING(f" ⚠️ Warning: {e}"))
|
71
|
+
else:
|
72
|
+
self.stdout.write(f" Would run: migrate {app_label} --database={db_name}")
|
73
|
+
else:
|
74
|
+
# Migrate all apps for this database (usually default)
|
75
|
+
self.stdout.write(f" 📦 Migrating all apps...")
|
76
|
+
if not dry_run:
|
77
|
+
try:
|
78
|
+
call_command("migrate", database=db_name, verbosity=1)
|
79
|
+
except Exception as e:
|
80
|
+
self.stdout.write(self.style.WARNING(f" ⚠️ Warning: {e}"))
|
81
|
+
else:
|
82
|
+
self.stdout.write(f" Would run: migrate --database={db_name}")
|
83
|
+
|
84
|
+
# Step 4: Migrate constance if needed
|
85
|
+
self.stdout.write(f"\n🔧 Migrating constance...")
|
86
|
+
if not dry_run:
|
87
|
+
try:
|
88
|
+
call_command("migrate", "constance", database="default", verbosity=1)
|
89
|
+
except Exception as e:
|
90
|
+
self.stdout.write(self.style.WARNING(f"⚠️ Constance warning: {e}"))
|
91
|
+
else:
|
92
|
+
self.stdout.write(" Would run: migrate constance --database=default")
|
93
|
+
|
94
|
+
self.stdout.write(self.style.SUCCESS("\n✅ All migrations completed!"))
|
95
|
+
|
96
|
+
def _get_app_label(self, app_path: str) -> str:
|
97
|
+
"""Convert full module path to Django app_label."""
|
98
|
+
try:
|
99
|
+
# Try to get app config by full path first
|
100
|
+
try:
|
101
|
+
app_config = apps.get_app_config(app_path)
|
102
|
+
return app_config.label
|
103
|
+
except LookupError:
|
104
|
+
pass
|
105
|
+
|
106
|
+
# Fallback: extract last part of the path as potential app_label
|
107
|
+
potential_label = app_path.split('.')[-1]
|
108
|
+
try:
|
109
|
+
app_config = apps.get_app_config(potential_label)
|
110
|
+
return app_config.label
|
111
|
+
except LookupError:
|
112
|
+
pass
|
113
|
+
|
114
|
+
return app_path
|
115
|
+
|
116
|
+
except Exception:
|
117
|
+
return app_path
|
@@ -0,0 +1,318 @@
|
|
1
|
+
# 🛡️ Django CFG Middleware
|
2
|
+
|
3
|
+
Custom Django middleware components for Django CFG applications.
|
4
|
+
|
5
|
+
## 📋 Contents
|
6
|
+
|
7
|
+
- [UserActivityMiddleware](#useractivitymiddleware) - User activity tracking
|
8
|
+
- [PublicEndpointsMiddleware](#publicendpointsmiddleware) - Ignore invalid JWT tokens on public endpoints
|
9
|
+
|
10
|
+
## UserActivityMiddleware
|
11
|
+
|
12
|
+
Middleware for automatic user activity tracking by updating the `last_login` field on API requests.
|
13
|
+
|
14
|
+
### ✨ Features
|
15
|
+
|
16
|
+
- ✅ Automatic `last_login` update on API requests
|
17
|
+
- ✅ Smart API request detection (JSON, DRF, REST methods)
|
18
|
+
- ✅ 5-minute update interval to prevent database spam
|
19
|
+
- ✅ In-memory caching for performance optimization
|
20
|
+
- ✅ Only works when `accounts` app is enabled
|
21
|
+
- ✅ KISS principle - no configuration needed
|
22
|
+
|
23
|
+
### 🚀 Automatic Integration
|
24
|
+
|
25
|
+
The middleware is automatically included when `enable_accounts = True`:
|
26
|
+
|
27
|
+
```python
|
28
|
+
class MyConfig(DjangoConfig):
|
29
|
+
enable_accounts = True # UserActivityMiddleware will be auto-included
|
30
|
+
```
|
31
|
+
|
32
|
+
### 🎯 API Request Detection
|
33
|
+
|
34
|
+
The middleware intelligently detects API requests using:
|
35
|
+
|
36
|
+
1. **JSON Content-Type or Accept header**
|
37
|
+
```
|
38
|
+
Content-Type: application/json
|
39
|
+
Accept: application/json
|
40
|
+
```
|
41
|
+
|
42
|
+
2. **DRF format parameter**
|
43
|
+
```
|
44
|
+
?format=json
|
45
|
+
?format=api
|
46
|
+
```
|
47
|
+
|
48
|
+
3. **REST methods** (POST, PUT, PATCH, DELETE) on non-admin paths
|
49
|
+
|
50
|
+
4. **Configured API prefixes**
|
51
|
+
- Django Revolution API: `/{api_prefix}/` (from config)
|
52
|
+
- Django CFG API: `/cfg/` (always)
|
53
|
+
|
54
|
+
### 📊 Statistics
|
55
|
+
|
56
|
+
Get middleware statistics:
|
57
|
+
|
58
|
+
```python
|
59
|
+
from django_cfg.middleware import UserActivityMiddleware
|
60
|
+
|
61
|
+
# In view or management command
|
62
|
+
middleware = UserActivityMiddleware()
|
63
|
+
stats = middleware.get_activity_stats()
|
64
|
+
|
65
|
+
print(stats)
|
66
|
+
# {
|
67
|
+
# 'tracked_users': 42,
|
68
|
+
# 'update_interval': 300,
|
69
|
+
# 'api_only': True,
|
70
|
+
# 'accounts_enabled': True,
|
71
|
+
# 'middleware_active': True
|
72
|
+
# }
|
73
|
+
```
|
74
|
+
|
75
|
+
### 🔍 Logging
|
76
|
+
|
77
|
+
The middleware logs activity at DEBUG level:
|
78
|
+
|
79
|
+
```python
|
80
|
+
# settings.py
|
81
|
+
LOGGING = {
|
82
|
+
'loggers': {
|
83
|
+
'django_cfg.middleware.user_activity': {
|
84
|
+
'level': 'DEBUG',
|
85
|
+
'handlers': ['console'],
|
86
|
+
},
|
87
|
+
},
|
88
|
+
}
|
89
|
+
```
|
90
|
+
|
91
|
+
### 🎛️ Manual Integration
|
92
|
+
|
93
|
+
If you need to include the middleware manually:
|
94
|
+
|
95
|
+
```python
|
96
|
+
# settings.py
|
97
|
+
MIDDLEWARE = [
|
98
|
+
# ... other middleware
|
99
|
+
'django_cfg.middleware.UserActivityMiddleware',
|
100
|
+
]
|
101
|
+
```
|
102
|
+
|
103
|
+
### 🔧 Performance
|
104
|
+
|
105
|
+
- **Caching**: Last update times are cached in memory
|
106
|
+
- **Batch updates**: Uses `update()` instead of `save()` for optimization
|
107
|
+
- **Auto-cleanup**: Cache automatically cleans up when exceeding 1000 users
|
108
|
+
- **Graceful errors**: Errors don't break request processing
|
109
|
+
|
110
|
+
### 🎯 Admin Integration
|
111
|
+
|
112
|
+
The `last_login` field is automatically displayed in accounts admin:
|
113
|
+
|
114
|
+
- ✅ In user list view (`last_login_display`)
|
115
|
+
- ✅ In user detail view
|
116
|
+
- ✅ With human-readable time format
|
117
|
+
|
118
|
+
### 🚨 Important Notes
|
119
|
+
|
120
|
+
1. **Accounts only**: Middleware only works when `enable_accounts = True`
|
121
|
+
2. **Authentication**: Only tracks authenticated users
|
122
|
+
3. **Performance**: 5-minute interval prevents database spam
|
123
|
+
4. **Safety**: Middleware doesn't break requests on errors
|
124
|
+
|
125
|
+
### 📈 Monitoring
|
126
|
+
|
127
|
+
For user activity monitoring:
|
128
|
+
|
129
|
+
```python
|
130
|
+
# In Django admin or management command
|
131
|
+
from django.contrib.auth import get_user_model
|
132
|
+
from django.utils import timezone
|
133
|
+
from datetime import timedelta
|
134
|
+
|
135
|
+
User = get_user_model()
|
136
|
+
|
137
|
+
# Active users in the last hour
|
138
|
+
active_users = User.objects.filter(
|
139
|
+
last_login__gte=timezone.now() - timedelta(hours=1)
|
140
|
+
).count()
|
141
|
+
|
142
|
+
# Online users (last 5 minutes)
|
143
|
+
online_users = User.objects.filter(
|
144
|
+
last_login__gte=timezone.now() - timedelta(minutes=5)
|
145
|
+
).count()
|
146
|
+
```
|
147
|
+
|
148
|
+
### 💡 Usage Examples
|
149
|
+
|
150
|
+
The middleware works automatically with no configuration needed:
|
151
|
+
|
152
|
+
```python
|
153
|
+
# Your DjangoConfig
|
154
|
+
class MyProjectConfig(DjangoConfig):
|
155
|
+
enable_accounts = True # That's it! Middleware is active
|
156
|
+
|
157
|
+
# API requests will automatically update last_login:
|
158
|
+
# POST /cfg/accounts/profile/
|
159
|
+
# GET /api/users/?format=json
|
160
|
+
# PUT /cfg/newsletter/subscribe/
|
161
|
+
```
|
162
|
+
|
163
|
+
## PublicEndpointsMiddleware
|
164
|
+
|
165
|
+
Middleware that temporarily removes invalid JWT tokens from public endpoints to prevent authentication errors.
|
166
|
+
|
167
|
+
### ✨ Features
|
168
|
+
|
169
|
+
- ✅ **Automatic activation** - No configuration needed, works out of the box
|
170
|
+
- ✅ **Smart endpoint detection** - Configurable regex patterns for public endpoints
|
171
|
+
- ✅ **JWT token detection** - Only processes requests with Bearer tokens
|
172
|
+
- ✅ **Temporary removal** - Auth headers are restored after request processing
|
173
|
+
- ✅ **Performance optimized** - Compiled regex patterns for fast matching
|
174
|
+
- ✅ **Detailed logging** - Debug information for troubleshooting
|
175
|
+
- ✅ **Statistics tracking** - Monitor middleware usage and effectiveness
|
176
|
+
|
177
|
+
### 🎯 Problem Solved
|
178
|
+
|
179
|
+
When a frontend sends an invalid/expired JWT token to a public endpoint (like OTP request), Django's authentication middleware tries to authenticate the user and fails with "User not found" errors, even though the endpoint has `AllowAny` permissions.
|
180
|
+
|
181
|
+
This middleware temporarily removes the `Authorization` header for public endpoints, allowing them to work without authentication errors.
|
182
|
+
|
183
|
+
### 🚀 Automatic Integration
|
184
|
+
|
185
|
+
The middleware is **automatically included** in all Django CFG projects:
|
186
|
+
|
187
|
+
```python
|
188
|
+
class MyConfig(DjangoConfig):
|
189
|
+
# No configuration needed - PublicEndpointsMiddleware is always active
|
190
|
+
pass
|
191
|
+
```
|
192
|
+
|
193
|
+
### 🎯 Default Public Endpoints
|
194
|
+
|
195
|
+
The middleware protects these endpoints by default:
|
196
|
+
|
197
|
+
```python
|
198
|
+
DEFAULT_PUBLIC_PATTERNS = [
|
199
|
+
r'^/api/accounts/otp/', # OTP endpoints (request, verify)
|
200
|
+
r'^/cfg/accounts/otp/', # CFG OTP endpoints
|
201
|
+
r'^/api/accounts/token/refresh/', # Token refresh
|
202
|
+
r'^/cfg/accounts/token/refresh/', # CFG Token refresh
|
203
|
+
r'^/api/health/', # Health check endpoints
|
204
|
+
r'^/cfg/api/health/', # CFG Health check endpoints
|
205
|
+
r'^/admin/login/', # Django admin login
|
206
|
+
r'^/api/schema/', # API schema endpoints
|
207
|
+
r'^/api/docs/', # API documentation
|
208
|
+
]
|
209
|
+
```
|
210
|
+
|
211
|
+
### ⚙️ Custom Configuration
|
212
|
+
|
213
|
+
You can customize public endpoint patterns in your Django settings:
|
214
|
+
|
215
|
+
```python
|
216
|
+
# settings.py (optional)
|
217
|
+
PUBLIC_ENDPOINT_PATTERNS = [
|
218
|
+
r'^/api/accounts/otp/',
|
219
|
+
r'^/api/public/',
|
220
|
+
r'^/api/webhooks/',
|
221
|
+
# Add your custom patterns here
|
222
|
+
]
|
223
|
+
```
|
224
|
+
|
225
|
+
### 🔍 How It Works
|
226
|
+
|
227
|
+
1. **Request Processing**: Middleware checks if the request path matches public endpoint patterns
|
228
|
+
2. **Token Detection**: If a Bearer token is present, it's temporarily removed
|
229
|
+
3. **Request Handling**: Django processes the request without authentication
|
230
|
+
4. **Token Restoration**: The original Authorization header is restored after processing
|
231
|
+
|
232
|
+
### 📊 Statistics
|
233
|
+
|
234
|
+
Get middleware statistics for monitoring:
|
235
|
+
|
236
|
+
```python
|
237
|
+
from django_cfg.middleware import PublicEndpointsMiddleware
|
238
|
+
|
239
|
+
# In your view or management command
|
240
|
+
middleware = PublicEndpointsMiddleware()
|
241
|
+
stats = middleware.get_stats()
|
242
|
+
|
243
|
+
print(stats)
|
244
|
+
# {
|
245
|
+
# 'requests_processed': 1250,
|
246
|
+
# 'tokens_ignored': 45,
|
247
|
+
# 'public_endpoints_hit': 120,
|
248
|
+
# 'public_patterns_count': 9,
|
249
|
+
# 'middleware_active': True
|
250
|
+
# }
|
251
|
+
```
|
252
|
+
|
253
|
+
### 🔍 Logging
|
254
|
+
|
255
|
+
The middleware logs activity at DEBUG level:
|
256
|
+
|
257
|
+
```python
|
258
|
+
# settings.py
|
259
|
+
LOGGING = {
|
260
|
+
'loggers': {
|
261
|
+
'django_cfg.middleware.public_endpoints': {
|
262
|
+
'level': 'DEBUG',
|
263
|
+
'handlers': ['console'],
|
264
|
+
},
|
265
|
+
},
|
266
|
+
}
|
267
|
+
```
|
268
|
+
|
269
|
+
### 🎛️ Manual Integration
|
270
|
+
|
271
|
+
If you need to include the middleware manually (not recommended):
|
272
|
+
|
273
|
+
```python
|
274
|
+
# settings.py
|
275
|
+
MIDDLEWARE = [
|
276
|
+
'django.middleware.security.SecurityMiddleware',
|
277
|
+
'corsheaders.middleware.CorsMiddleware',
|
278
|
+
'django_cfg.middleware.PublicEndpointsMiddleware', # Add early in stack
|
279
|
+
# ... other middleware
|
280
|
+
]
|
281
|
+
```
|
282
|
+
|
283
|
+
### 🚨 Important Notes
|
284
|
+
|
285
|
+
1. **Always Active**: Middleware is included by default in all Django CFG projects
|
286
|
+
2. **Performance**: Uses compiled regex patterns for fast endpoint matching
|
287
|
+
3. **Safety**: Only removes Authorization headers temporarily, restores them after processing
|
288
|
+
4. **Logging**: All actions are logged for debugging and monitoring
|
289
|
+
|
290
|
+
### 💡 Usage Examples
|
291
|
+
|
292
|
+
The middleware works automatically with no configuration needed:
|
293
|
+
|
294
|
+
```python
|
295
|
+
# Your DjangoConfig
|
296
|
+
class MyProjectConfig(DjangoConfig):
|
297
|
+
# PublicEndpointsMiddleware is automatically active
|
298
|
+
pass
|
299
|
+
|
300
|
+
# These requests will work even with invalid tokens:
|
301
|
+
# POST /api/accounts/otp/request/ (with expired Bearer token)
|
302
|
+
# POST /cfg/accounts/otp/verify/ (with invalid Bearer token)
|
303
|
+
# GET /api/health/ (with any Bearer token)
|
304
|
+
```
|
305
|
+
|
306
|
+
### 🔧 Frontend Integration
|
307
|
+
|
308
|
+
Perfect companion to frontend error handling:
|
309
|
+
|
310
|
+
```typescript
|
311
|
+
// Frontend automatically clears invalid tokens on 401/403
|
312
|
+
// Middleware ensures public endpoints work during token cleanup
|
313
|
+
const response = await api.requestOTP({
|
314
|
+
identifier: "user@example.com",
|
315
|
+
channel: "email"
|
316
|
+
});
|
317
|
+
// ✅ Works even if localStorage has invalid token
|
318
|
+
```
|