django-cfg 1.2.5__py3-none-any.whl → 1.2.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
django_cfg/__init__.py CHANGED
@@ -32,7 +32,7 @@ Example:
32
32
  default_app_config = "django_cfg.apps.DjangoCfgConfig"
33
33
 
34
34
  # Version information
35
- __version__ = "1.2.5"
35
+ __version__ = "1.2.6"
36
36
  __license__ = "MIT"
37
37
 
38
38
  # Import registry for organized lazy loading
@@ -6,8 +6,7 @@ from django.contrib import admin
6
6
  from django.contrib.humanize.templatetags.humanize import naturaltime
7
7
  from django.utils.html import format_html
8
8
  from unfold.admin import ModelAdmin
9
- from import_export.admin import ExportMixin
10
- from unfold.contrib.import_export.forms import ExportForm
9
+ from django_cfg import ExportMixin, ExportForm
11
10
 
12
11
  from ..models import TwilioResponse
13
12
  from .filters import TwilioResponseStatusFilter, TwilioResponseTypeFilter
@@ -12,14 +12,19 @@ from unfold.admin import ModelAdmin
12
12
  from unfold.forms import AdminPasswordChangeForm, UserChangeForm, UserCreationForm
13
13
  from unfold.decorators import action
14
14
  from unfold.enums import ActionVariant
15
+ from django_cfg import ImportExportModelAdmin
15
16
 
16
17
  from ..models import CustomUser
17
18
  from .filters import UserStatusFilter
18
19
  from .inlines import UserRegistrationSourceInline, UserActivityInline, UserEmailLogInline, UserSupportTicketsInline
20
+ from .resources import CustomUserResource
19
21
 
20
22
 
21
23
  @admin.register(CustomUser)
22
- class CustomUserAdmin(BaseUserAdmin, ModelAdmin):
24
+ class CustomUserAdmin(BaseUserAdmin, ModelAdmin, ImportExportModelAdmin):
25
+ # Import/Export configuration
26
+ resource_class = CustomUserResource
27
+
23
28
  # Forms loaded from `unfold.forms`
24
29
  form = UserChangeForm
25
30
  add_form = UserCreationForm
@@ -200,3 +200,86 @@ class UserActivity(models.Model):
200
200
 
201
201
  def __str__(self):
202
202
  return f"{self.user.username} - {self.get_activity_type_display()}"
203
+
204
+
205
+ class TwilioResponse(models.Model):
206
+ """Model for storing Twilio API responses and webhook data."""
207
+
208
+ RESPONSE_TYPES = [
209
+ ('api_send', 'API Send Request'),
210
+ ('api_verify', 'API Verify Request'),
211
+ ('webhook_status', 'Webhook Status Update'),
212
+ ('webhook_delivery', 'Webhook Delivery Report'),
213
+ ]
214
+
215
+ SERVICE_TYPES = [
216
+ ('whatsapp', 'WhatsApp'),
217
+ ('sms', 'SMS'),
218
+ ('voice', 'Voice'),
219
+ ('email', 'Email'),
220
+ ('verify', 'Verify API'),
221
+ ]
222
+
223
+ response_type = models.CharField(max_length=20, choices=RESPONSE_TYPES)
224
+ service_type = models.CharField(max_length=10, choices=SERVICE_TYPES)
225
+
226
+ # Twilio identifiers
227
+ message_sid = models.CharField(max_length=34, blank=True, help_text="Twilio Message SID")
228
+ verification_sid = models.CharField(max_length=34, blank=True, help_text="Twilio Verification SID")
229
+
230
+ # Request/Response data
231
+ request_data = models.JSONField(default=dict, help_text="Original request parameters")
232
+ response_data = models.JSONField(default=dict, help_text="Twilio API response")
233
+
234
+ # Status and error handling
235
+ status = models.CharField(max_length=20, blank=True, help_text="Message/Verification status")
236
+ error_code = models.CharField(max_length=10, blank=True, help_text="Twilio error code")
237
+ error_message = models.TextField(blank=True, help_text="Error description")
238
+
239
+ # Contact information
240
+ to_number = models.CharField(max_length=20, blank=True, help_text="Recipient phone/email")
241
+ from_number = models.CharField(max_length=20, blank=True, help_text="Sender phone/email")
242
+
243
+ # Pricing
244
+ price = models.DecimalField(max_digits=10, decimal_places=6, null=True, blank=True)
245
+ price_unit = models.CharField(max_length=3, blank=True, help_text="Currency code")
246
+
247
+ # Timestamps
248
+ created_at = models.DateTimeField(auto_now_add=True)
249
+ updated_at = models.DateTimeField(auto_now=True)
250
+ twilio_created_at = models.DateTimeField(null=True, blank=True, help_text="Timestamp from Twilio")
251
+
252
+ # Relations
253
+ otp_secret = models.ForeignKey(
254
+ 'OTPSecret',
255
+ on_delete=models.SET_NULL,
256
+ null=True,
257
+ blank=True,
258
+ related_name='twilio_responses',
259
+ help_text="Related OTP if applicable"
260
+ )
261
+
262
+ class Meta:
263
+ app_label = 'django_cfg_accounts'
264
+ verbose_name = 'Twilio Response'
265
+ verbose_name_plural = 'Twilio Responses'
266
+ ordering = ['-created_at']
267
+ indexes = [
268
+ models.Index(fields=['message_sid']),
269
+ models.Index(fields=['verification_sid']),
270
+ models.Index(fields=['status', 'created_at']),
271
+ models.Index(fields=['response_type', 'service_type']),
272
+ ]
273
+
274
+ def __str__(self):
275
+ return f"{self.get_response_type_display()} - {self.get_service_type_display()}"
276
+
277
+ @property
278
+ def has_error(self):
279
+ """Check if response has error."""
280
+ return bool(self.error_code or self.error_message)
281
+
282
+ @property
283
+ def is_successful(self):
284
+ """Check if response is successful."""
285
+ return not self.has_error and self.status in ['sent', 'delivered', 'approved']
@@ -4,8 +4,7 @@ from django.utils.html import format_html
4
4
  from django.http import HttpResponseRedirect
5
5
  from unfold.admin import ModelAdmin
6
6
  from unfold.decorators import action
7
- from import_export.admin import ImportExportModelAdmin
8
- from unfold.contrib.import_export.forms import ImportForm, ExportForm
7
+ from django_cfg import ImportExportModelAdmin, ImportForm, ExportForm
9
8
 
10
9
  from ..models import Lead
11
10
  from .resources import LeadResource
@@ -7,8 +7,7 @@ from unfold.admin import ModelAdmin
7
7
  from unfold.decorators import action
8
8
  from unfold.contrib.forms.widgets import WysiwygWidget
9
9
  from unfold.enums import ActionVariant
10
- from import_export.admin import ImportExportModelAdmin, ExportMixin
11
- from unfold.contrib.import_export.forms import ImportForm, ExportForm
10
+ from django_cfg import ImportExportModelAdmin, ExportMixin, ImportForm, ExportForm
12
11
 
13
12
  from ..models import EmailLog, Newsletter, NewsletterSubscription, NewsletterCampaign
14
13
  from .filters import UserEmailFilter, UserNameFilter, HasUserFilter, EmailOpenedFilter, EmailClickedFilter
@@ -7,8 +7,7 @@ from django.urls import reverse
7
7
  from django.shortcuts import redirect
8
8
  from django.http import HttpRequest
9
9
  from django.utils.translation import gettext_lazy as _
10
- from import_export.admin import ExportMixin
11
- from unfold.contrib.import_export.forms import ExportForm
10
+ from django_cfg import ExportMixin, ExportForm
12
11
 
13
12
  from ..models import Ticket, Message
14
13
  from .filters import TicketUserEmailFilter, TicketUserNameFilter, MessageSenderEmailFilter
@@ -404,6 +404,8 @@ class SettingsGenerator:
404
404
 
405
405
  # Check for Constance configuration
406
406
  if hasattr(config, "constance") and config.constance:
407
+ # Set config reference for app fields detection
408
+ config.constance.set_config(config)
407
409
  constance_settings = config.constance.to_django_settings()
408
410
  settings.update(constance_settings)
409
411
  integrations.append("constance")
@@ -8,6 +8,7 @@ Unfold admin integration and smart field grouping.
8
8
  from typing import Dict, List, Optional, Any, Union, Literal
9
9
  from pydantic import BaseModel, Field, field_validator
10
10
  from pathlib import Path
11
+ from django_cfg.models.cfg import BaseCfgAutoModule
11
12
 
12
13
 
13
14
  class ConstanceField(BaseModel):
@@ -37,7 +38,7 @@ class ConstanceField(BaseModel):
37
38
  max_length=500,
38
39
  )
39
40
 
40
- field_type: Literal["str", "int", "float", "bool", "choice"] = Field(
41
+ field_type: Literal["str", "int", "float", "bool", "choice", "longtext"] = Field(
41
42
  default="str",
42
43
  description="Field type for form rendering and validation",
43
44
  )
@@ -87,6 +88,10 @@ class ConstanceField(BaseModel):
87
88
  "django.forms.CharField",
88
89
  {"widget": "unfold.widgets.UnfoldAdminTextInputWidget"},
89
90
  ],
91
+ "longtext": [
92
+ "django.forms.CharField",
93
+ {"widget": "unfold.widgets.UnfoldAdminTextareaWidget"},
94
+ ],
90
95
  "int": [
91
96
  "django.forms.IntegerField",
92
97
  {"widget": "unfold.widgets.UnfoldAdminIntegerFieldWidget"},
@@ -104,7 +109,7 @@ class ConstanceField(BaseModel):
104
109
  return field_mapping.get(self.field_type, field_mapping["str"])
105
110
 
106
111
 
107
- class ConstanceConfig(BaseModel):
112
+ class ConstanceConfig(BaseModel, BaseCfgAutoModule):
108
113
  """
109
114
  Django Constance configuration with automatic Unfold integration.
110
115
 
@@ -146,15 +151,46 @@ class ConstanceConfig(BaseModel):
146
151
  description="List of Constance fields",
147
152
  )
148
153
 
154
+ def _get_app_constance_fields(self) -> List[ConstanceField]:
155
+ """Automatically collect constance fields from django-cfg apps."""
156
+ app_fields = []
157
+ config = self.get_config()
158
+
159
+ # Get fields from knowbase app (only if enabled)
160
+ if config and getattr(config, 'enable_knowbase', False):
161
+ try:
162
+ from django_cfg.apps.knowbase.config import get_django_cfg_knowbase_constance_fields
163
+ knowbase_fields = get_django_cfg_knowbase_constance_fields()
164
+ app_fields.extend(knowbase_fields)
165
+ except (ImportError, Exception):
166
+ pass
167
+
168
+ # Get fields from tasks app (only if knowbase or agents are enabled)
169
+ if config and (getattr(config, 'enable_knowbase', False) or getattr(config, 'enable_agents', False)):
170
+ try:
171
+ from django_cfg.modules.django_tasks import extend_constance_config_with_tasks
172
+ tasks_fields = extend_constance_config_with_tasks()
173
+ app_fields.extend(tasks_fields)
174
+ except (ImportError, Exception):
175
+ pass
176
+
177
+ return app_fields
178
+
179
+ def get_all_fields(self) -> List[ConstanceField]:
180
+ """Get all constance fields including app fields."""
181
+ all_fields = list(self.fields) # User-defined fields
182
+ all_fields.extend(self._get_app_constance_fields()) # App fields
183
+ return all_fields
184
+
149
185
  def get_config_dict(self) -> Dict[str, tuple[Any, str]]:
150
186
  """Generate CONSTANCE_CONFIG dictionary."""
151
- return {field.name: field.to_constance_config() for field in self.fields}
187
+ return {field.name: field.to_constance_config() for field in self.get_all_fields()}
152
188
 
153
189
  def get_fieldsets_dict(self) -> Dict[str, List[str]]:
154
190
  """Generate CONSTANCE_FIELDSETS dictionary grouped by field groups."""
155
191
  fieldsets = {}
156
192
 
157
- for field in self.fields:
193
+ for field in self.get_all_fields():
158
194
  group = field.group
159
195
  if group not in fieldsets:
160
196
  fieldsets[group] = []
@@ -178,13 +214,16 @@ class ConstanceConfig(BaseModel):
178
214
 
179
215
  def to_django_settings(self) -> Dict[str, Any]:
180
216
  """Generate Django settings for Constance."""
181
- if not self.fields:
217
+ all_fields = self.get_all_fields()
218
+ if not all_fields:
182
219
  return {}
183
220
 
184
221
  settings = {
185
222
  # Main configuration
186
223
  "CONSTANCE_CONFIG": self.get_config_dict(),
187
224
  "CONSTANCE_FIELDSETS": self.get_fieldsets_dict(),
225
+ # Constance internal fieldsets (for admin)
226
+ "CONSTANCE_CONFIG_FIELDSETS": self.get_fieldsets_dict(),
188
227
  # Backend settings (using default database backend)
189
228
  "CONSTANCE_BACKEND": "constance.backends.database.DatabaseBackend",
190
229
  # Cache settings
@@ -203,4 +242,12 @@ class ConstanceConfig(BaseModel):
203
242
  # Remove None values
204
243
  return {k: v for k, v in settings.items() if v is not None}
205
244
 
245
+ def get_smart_defaults(self):
246
+ """Get smart default configuration for this module."""
247
+ return ConstanceConfig()
248
+
249
+ def get_module_config(self):
250
+ """Get the final configuration for this module."""
251
+ return self
252
+
206
253
 
@@ -0,0 +1,81 @@
1
+ # Django Import/Export Integration
2
+
3
+ Simple integration with `django-import-export` package through django-cfg registry system.
4
+
5
+ ## Features
6
+
7
+ - 🔗 **Registry Integration**: Access django-import-export components through django-cfg imports
8
+ - 🎨 **Unfold Styling**: Automatic beautiful styling through unfold admin interface
9
+ - 📦 **Zero Overhead**: Direct re-exports without unnecessary wrappers
10
+ - 🚀 **Full Compatibility**: 100% compatible with original django-import-export
11
+
12
+ ## Quick Start
13
+
14
+ ```python
15
+ from django_cfg import ImportExportModelAdmin, BaseResource
16
+
17
+ class VehicleResource(BaseResource):
18
+ class Meta:
19
+ model = Vehicle
20
+ fields = ('id', 'brand', 'model', 'year', 'price')
21
+
22
+ @admin.register(Vehicle)
23
+ class VehicleAdmin(ImportExportModelAdmin):
24
+ resource_class = VehicleResource
25
+ list_display = ('brand', 'model', 'year', 'price')
26
+ ```
27
+
28
+ ## Available Components
29
+
30
+ All components are direct re-exports from `django-import-export`:
31
+
32
+ ### Admin Classes
33
+ - `ImportExportMixin` - Mixin for adding import/export to existing admin
34
+ - `ImportExportModelAdmin` - Complete admin class with import/export
35
+
36
+ ### Forms
37
+ - `ImportForm` - Standard import form
38
+ - `ExportForm` - Standard export form
39
+ - `SelectableFieldsExportForm` - Form for selecting fields to export
40
+
41
+ ### Resources
42
+ - `BaseResource` - Base resource class (alias for `ModelResource`)
43
+
44
+ ## Why This Approach?
45
+
46
+ Instead of creating unnecessary wrappers, this module simply:
47
+
48
+ 1. **Re-exports** original django-import-export components
49
+ 2. **Integrates** them into django-cfg registry for consistent imports
50
+ 3. **Relies** on unfold for beautiful styling
51
+ 4. **Maintains** 100% compatibility with original package
52
+
53
+ ## Usage
54
+
55
+ ```python
56
+ # Instead of:
57
+ from import_export.admin import ImportExportModelAdmin
58
+ from import_export.resources import ModelResource
59
+
60
+ # Use:
61
+ from django_cfg import ImportExportModelAdmin, BaseResource
62
+ ```
63
+
64
+ ## Configuration
65
+
66
+ No additional configuration needed. Just install `django-import-export`:
67
+
68
+ ```bash
69
+ pip install django-import-export
70
+ ```
71
+
72
+ The module automatically works with:
73
+ - Unfold admin interface styling
74
+ - Django-cfg configuration system
75
+ - All original django-import-export features
76
+
77
+ ## Full Documentation
78
+
79
+ For complete documentation, see the official [django-import-export docs](https://django-import-export.readthedocs.io/).
80
+
81
+ This module adds no additional functionality - it's purely for convenience and consistency within the django-cfg ecosystem.
@@ -0,0 +1,43 @@
1
+ """
2
+ Django Import/Export Integration for Django CFG
3
+
4
+ Simple re-export of django-import-export components through django-cfg registry.
5
+ Provides seamless integration without unnecessary wrappers.
6
+ """
7
+
8
+ # Re-export original classes through django-cfg registry
9
+ from import_export.admin import ImportExportMixin as BaseImportExportMixin, ImportExportModelAdmin as BaseImportExportModelAdmin, ExportMixin as BaseExportMixin, ImportMixin as BaseImportMixin
10
+ from import_export.resources import ModelResource as BaseResource
11
+ from import_export.forms import ImportForm, ExportForm, SelectableFieldsExportForm
12
+
13
+
14
+ class ImportExportMixin(BaseImportExportMixin):
15
+ """Django-CFG enhanced ImportExportMixin with custom templates."""
16
+ change_list_template = 'admin/import_export/change_list_import_export.html'
17
+
18
+
19
+ class ImportExportModelAdmin(BaseImportExportModelAdmin):
20
+ """Django-CFG enhanced ImportExportModelAdmin with custom templates."""
21
+ change_list_template = 'admin/import_export/change_list_import_export.html'
22
+
23
+
24
+ class ExportMixin(BaseExportMixin):
25
+ """Django-CFG enhanced ExportMixin with custom templates."""
26
+ change_list_template = 'admin/import_export/change_list_export.html'
27
+
28
+
29
+ class ImportMixin(BaseImportMixin):
30
+ """Django-CFG enhanced ImportMixin with custom templates."""
31
+ change_list_template = 'admin/import_export/change_list_import.html'
32
+
33
+
34
+ __all__ = [
35
+ 'ImportExportMixin',
36
+ 'ImportExportModelAdmin',
37
+ 'ExportMixin',
38
+ 'ImportMixin',
39
+ 'BaseResource',
40
+ 'ImportForm',
41
+ 'ExportForm',
42
+ 'SelectableFieldsExportForm',
43
+ ]
@@ -9,4 +9,14 @@ MODULES_REGISTRY = {
9
9
 
10
10
  # Configuration utilities
11
11
  "set_current_config": ("django_cfg.core.config", "set_current_config"),
12
+
13
+ # Import/Export integration (simple re-exports)
14
+ "ImportForm": ("django_cfg.modules.django_import_export", "ImportForm"),
15
+ "ExportForm": ("django_cfg.modules.django_import_export", "ExportForm"),
16
+ "SelectableFieldsExportForm": ("django_cfg.modules.django_import_export", "SelectableFieldsExportForm"),
17
+ "ImportExportMixin": ("django_cfg.modules.django_import_export", "ImportExportMixin"),
18
+ "ImportExportModelAdmin": ("django_cfg.modules.django_import_export", "ImportExportModelAdmin"),
19
+ "ExportMixin": ("django_cfg.modules.django_import_export", "ExportMixin"),
20
+ "ImportMixin": ("django_cfg.modules.django_import_export", "ImportMixin"),
21
+ "BaseResource": ("django_cfg.modules.django_import_export", "BaseResource"),
12
22
  }
@@ -0,0 +1,24 @@
1
+ {% extends "admin/change_list.html" %}
2
+ {% load admin_urls i18n %}
3
+
4
+ {% block object-tools %}
5
+ {# Export only button #}
6
+ <div class="ml-2 flex flex-row items-center gap-2">
7
+ {% if has_export_permission %}
8
+ <a href="{% url opts|admin_urlname:'export' %}{{ cl.get_query_string }}"
9
+ class="bg-white border border-base-200 cursor-pointer flex font-medium gap-2 items-center px-3 py-2 rounded-default shadow-xs text-sm hover:text-primary-600 dark:bg-base-900 dark:border-base-700 dark:hover:text-primary-500">
10
+ <span class="material-symbols-outlined">download</span>
11
+ {% trans "Export" %}
12
+ </a>
13
+ {% endif %}
14
+
15
+ {# Add button and other standard tools #}
16
+ {% if has_add_permission %}
17
+ <a href="{% url cl.opts|admin_urlname:'add' %}{% if is_popup %}?{{ popup_var }}=1{% endif %}"
18
+ class="addlink bg-primary-600 flex items-center h-9 justify-center -my-1 rounded-full w-9"
19
+ title="{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}">
20
+ <span class="material-symbols-outlined text-white">add</span>
21
+ </a>
22
+ {% endif %}
23
+ </div>
24
+ {% endblock %}
@@ -0,0 +1,24 @@
1
+ {% extends "admin/change_list.html" %}
2
+ {% load admin_urls i18n %}
3
+
4
+ {% block object-tools %}
5
+ {# Import only button #}
6
+ <div class="ml-2 flex flex-row items-center gap-2">
7
+ {% if has_import_permission %}
8
+ <a href="{% url opts|admin_urlname:"import" %}"
9
+ class="bg-white border border-base-200 cursor-pointer flex font-medium gap-2 items-center px-3 py-2 rounded-default shadow-xs text-sm hover:text-primary-600 dark:bg-base-900 dark:border-base-700 dark:hover:text-primary-500">
10
+ <span class="material-symbols-outlined">upload</span>
11
+ {% trans "Import" %}
12
+ </a>
13
+ {% endif %}
14
+
15
+ {# Add button and other standard tools #}
16
+ {% if has_add_permission %}
17
+ <a href="{% url cl.opts|admin_urlname:'add' %}{% if is_popup %}?{{ popup_var }}=1{% endif %}"
18
+ class="addlink bg-primary-600 flex items-center h-9 justify-center -my-1 rounded-full w-9"
19
+ title="{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}">
20
+ <span class="material-symbols-outlined text-white">add</span>
21
+ </a>
22
+ {% endif %}
23
+ </div>
24
+ {% endblock %}
@@ -0,0 +1,34 @@
1
+ {% extends "admin/change_list.html" %}
2
+ {% load admin_urls i18n %}
3
+
4
+ {% block object-tools %}
5
+ {# Override object-tools to integrate import/export buttons into unfold header #}
6
+ <div class="ml-2 flex flex-row items-center gap-2">
7
+ {# Import button #}
8
+ {% if has_import_permission %}
9
+ <a href="{% url opts|admin_urlname:"import" %}"
10
+ class="bg-white border border-base-200 cursor-pointer flex font-medium gap-2 items-center px-3 py-2 rounded-default shadow-xs text-sm hover:text-primary-600 dark:bg-base-900 dark:border-base-700 dark:hover:text-primary-500">
11
+ <span class="material-symbols-outlined">upload</span>
12
+ {% trans "Import" %}
13
+ </a>
14
+ {% endif %}
15
+
16
+ {# Export button #}
17
+ {% if has_export_permission %}
18
+ <a href="{% url opts|admin_urlname:'export' %}{{ cl.get_query_string }}"
19
+ class="bg-white border border-base-200 cursor-pointer flex font-medium gap-2 items-center px-3 py-2 rounded-default shadow-xs text-sm hover:text-primary-600 dark:bg-base-900 dark:border-base-700 dark:hover:text-primary-500">
20
+ <span class="material-symbols-outlined">download</span>
21
+ {% trans "Export" %}
22
+ </a>
23
+ {% endif %}
24
+
25
+ {# Add button and other standard tools #}
26
+ {% if has_add_permission %}
27
+ <a href="{% url cl.opts|admin_urlname:'add' %}{% if is_popup %}?{{ popup_var }}=1{% endif %}"
28
+ class="addlink bg-primary-600 flex items-center h-9 justify-center -my-1 rounded-full w-9"
29
+ title="{% blocktrans with cl.opts.verbose_name as name %}Add {{ name }}{% endblocktrans %}">
30
+ <span class="material-symbols-outlined text-white">add</span>
31
+ </a>
32
+ {% endif %}
33
+ </div>
34
+ {% endblock %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.2.5
3
+ Version: 1.2.6
4
4
  Summary: 🚀 Next-gen Django configuration: type-safety, AI features, blazing-fast setup, and automated best practices — all in one.
5
5
  Project-URL: Homepage, https://django-cfg.com
6
6
  Project-URL: Documentation, https://django-cfg.com
@@ -1,5 +1,5 @@
1
1
  django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- django_cfg/__init__.py,sha256=7xxzM_weNWt9rcTcCCF7ubv7Zep_cM7TAfgYUMq45hw,1630
2
+ django_cfg/__init__.py,sha256=NKc91hld5F7xZ4qX35SX37LFIHySvpScQfJ8GfT_xHw,1630
3
3
  django_cfg/apps.py,sha256=k84brkeXJI7EgKZLEpTkM9YFZofKI4PzhFOn1cl9Msc,1656
4
4
  django_cfg/config.py,sha256=0cuRJVEnf03WzvEqhwzLvn9Zi1805C5KG1yk27ekABA,1190
5
5
  django_cfg/urls.py,sha256=bpRFjMonQuk4UCUMxx4ueBX3YDNB7HXKFwEghQ3KR3o,793
@@ -8,7 +8,7 @@ django_cfg/apps/urls.py,sha256=xdRTe1bMzF753cH5tw9peIwr21kciy13I368b_JyWk0,2118
8
8
  django_cfg/apps/accounts/README.md,sha256=YkUYJ3iKMYTmm9ALK2PDnX75SDqZxgnkzNLCD5efxRs,8227
9
9
  django_cfg/apps/accounts/__init__.py,sha256=osecEQhMJVP8ejhZzElNsAqA1fX-GPD3K5_yNwDk6IE,100
10
10
  django_cfg/apps/accounts/apps.py,sha256=Xd4XNpY1tw3zOqk_M9L6MR6oFdfFMYrfmrmbj0uelUs,492
11
- django_cfg/apps/accounts/models.py,sha256=EiI5dWtEkyp9D73yH-QWhonm88a5RoPKoYwXyaSsyNk,6953
11
+ django_cfg/apps/accounts/models.py,sha256=65AomWYd78ptQ60drPbodxf0Ue310vmJQpQOPHL6V3E,10161
12
12
  django_cfg/apps/accounts/signals.py,sha256=oIMM0H4FySCWDsavcVeBYppokVghfWTND6YrPpWM5oo,6351
13
13
  django_cfg/apps/accounts/urls.py,sha256=x3-0UMe8TKsuJ_GyC2hW0Un7wvnIVfuUSJ_x4HN5FWY,1334
14
14
  django_cfg/apps/accounts/admin/__init__.py,sha256=6lzAXnF9vQJm0x1lvsq0O-IWMWluIKqbQTfdF7eDOMo,439
@@ -19,8 +19,8 @@ django_cfg/apps/accounts/admin/inlines.py,sha256=6LE-DHchbxysl4NqAwRr7ZcEnZFiQ6j
19
19
  django_cfg/apps/accounts/admin/otp.py,sha256=M1HSVObxpQxxC82f8ivVGzdHBv-R9dVpDnaINDDRY4E,1517
20
20
  django_cfg/apps/accounts/admin/registration_source.py,sha256=mct-Dg7jx1fF9z-1YJZaKPe7HoyZiCWib8ogN6pGIlQ,2851
21
21
  django_cfg/apps/accounts/admin/resources.py,sha256=ZCs8Yl6r_m8bQuYQuzmymCnd1IvKAtdQLneOFC1yBD4,7511
22
- django_cfg/apps/accounts/admin/twilio_response.py,sha256=0K424Yn1Gle41i7xCuFs821GxYQnJ3NurFhazdH8NrQ,6950
23
- django_cfg/apps/accounts/admin/user.py,sha256=xWmm3X6OeJEjC_zen11sulWC2nDVPHV_FGVEGAp7Q3M,10243
22
+ django_cfg/apps/accounts/admin/twilio_response.py,sha256=4Vfurfxe1tO6IgP5fFSOjCFR1ziUt9ll83oMPQmojBk,6895
23
+ django_cfg/apps/accounts/admin/user.py,sha256=wfG30tLACJiFDZ2gnOpqSrsRYbMLoWP33yQk3h-wCzU,10434
24
24
  django_cfg/apps/accounts/management/commands/test_otp.py,sha256=NPlANZtGgq9kqOHWneaTyWUIsyvpIbrP6wM0jASSfhA,6980
25
25
  django_cfg/apps/accounts/managers/__init__.py,sha256=NtY-cQl-6TUVum9HEVud4RKbR72xEiYzK14mbd9Y2Y0,50
26
26
  django_cfg/apps/accounts/managers/user_manager.py,sha256=OzLdOxZEIru2-ttg0XN7WctQmZ9xiD-Avt-dtlXef5U,9949
@@ -195,7 +195,7 @@ django_cfg/apps/leads/tests.py,sha256=uM7qcaJfNT-fFjla5s4vr7hQiGzXf7CUzqyX1QDwwf
195
195
  django_cfg/apps/leads/urls.py,sha256=KFCdB9x0LySJODeUElQ2c-dxcl_z79xzYNC_9i6vFPk,355
196
196
  django_cfg/apps/leads/views.py,sha256=3tnnxAwEnD_ycIhZeIvTqzOyNaMTA00gxnbywtnPe8A,3212
197
197
  django_cfg/apps/leads/admin/__init__.py,sha256=81WXUqQ5lACzV_G8n_PdPIoGeb95NKow_xcHv-Y13YM,111
198
- django_cfg/apps/leads/admin/leads_admin.py,sha256=VGLYkXPln4ObaXaR2Y9GeUcELHDfG83iRuow9Fvng1U,2556
198
+ django_cfg/apps/leads/admin/leads_admin.py,sha256=q1d1kmTWZUCUHxePOlDrwF9jJvgjN75-srWnllvwHJM,2501
199
199
  django_cfg/apps/leads/admin/resources.py,sha256=bJdydBmPMZ08N5_IylaZEtSY4JySs1-h9pJoKFm04BA,3742
200
200
  django_cfg/apps/leads/migrations/0001_initial.py,sha256=mBDupgmgmaLQFO9bLaBOODN7pervwAnN_EfsS08MoB4,4876
201
201
  django_cfg/apps/leads/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -210,7 +210,7 @@ django_cfg/apps/newsletter/signals.py,sha256=0wkOxEXnwBnLA1B72sZ_nb_x2ycsvQSQ3jv
210
210
  django_cfg/apps/newsletter/urls.py,sha256=Zfbgj0NZ06dMu503JOn4GGgmKpQ3tOjTIyUmEslaJdE,1609
211
211
  django_cfg/apps/newsletter/admin/__init__.py,sha256=dXCym_3qp9HxT0sUV_LBGgEkKv1k_Mj3a0TTZYnH2yI,290
212
212
  django_cfg/apps/newsletter/admin/filters.py,sha256=lPMtHULDOisTsN9_2BMoGu23ICkFEJDZst5Fhj5Sv5c,3675
213
- django_cfg/apps/newsletter/admin/newsletter_admin.py,sha256=QJ-28f7LW7E5F8xfihYtjbbzUBNu4kqiFhTwHWQcEaQ,9508
213
+ django_cfg/apps/newsletter/admin/newsletter_admin.py,sha256=DuXbKlgYgObD4-XzoGuzG1gKllm4YfhGwFfB-IV10XM,9453
214
214
  django_cfg/apps/newsletter/admin/resources.py,sha256=BGgKJSvUG5ZBOZiZ9YymAm2TE5BY8IXB8t-DgUHpbzA,6956
215
215
  django_cfg/apps/newsletter/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
216
216
  django_cfg/apps/newsletter/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -238,7 +238,7 @@ django_cfg/apps/support/urls.py,sha256=t3r4wGRUqQS-BDCQgSXwSF9pbucyvr7lo7_pJ1uZ5
238
238
  django_cfg/apps/support/admin/__init__.py,sha256=vVoUWfKj6qBHhwr6zG2ZH8ZpUegYNJvzuAxdFoHEo_0,153
239
239
  django_cfg/apps/support/admin/filters.py,sha256=ZpKtetRxppRAMwIr-pwDbXAyh7qouDfTCEZoo1YJfFs,2179
240
240
  django_cfg/apps/support/admin/resources.py,sha256=8F0s_3Taz5LCUwlxdRPEcM9tkf08ZS0jBrHc2yHzXb4,5033
241
- django_cfg/apps/support/admin/support_admin.py,sha256=UEz4f12VQ_fZeykpC2DG3qOuw101O-7Ptxbq5imTVOk,9237
241
+ django_cfg/apps/support/admin/support_admin.py,sha256=W9Lpbw3QxPzx3PZrm-YtJqU0ssDT3O64bzFXuISuc18,9182
242
242
  django_cfg/apps/support/managers/message_manager.py,sha256=lwfhkuCksIRHL_6563irk6pS0IHvHma9VVVqBMVuq7s,1159
243
243
  django_cfg/apps/support/managers/ticket_manager.py,sha256=SEoiGvesTNEZtrwS7HC76F_-fVbDqQrcL5zyO7Mpkl4,3058
244
244
  django_cfg/apps/support/migrations/0001_initial.py,sha256=AUUXqMiRbv_bRhogBWKWdrxvHpCXxzS2Ku4O6pkq3nU,2986
@@ -287,7 +287,7 @@ django_cfg/core/__init__.py,sha256=eVK57qFOok9kTeHoNEMQ1BplkUOaQ7NB9kP9eQK1vg0,3
287
287
  django_cfg/core/config.py,sha256=XZmW4tqHYi8zUOywpJ_8DqeFUzwwflMshZnwrpddjtw,26302
288
288
  django_cfg/core/environment.py,sha256=MAoEPqIPsLVhSANT2Bz4nnus2wmbMW0RCOQxhQfDrDc,9106
289
289
  django_cfg/core/exceptions.py,sha256=RTQEoU3PfR8lqqNNv5ayd_HY2yJLs3eioqUy8VM6AG4,10378
290
- django_cfg/core/generation.py,sha256=OJjf54QmsbWAEEyrvO2AoPONP-8eK3zU4YDWe2w-H8E,22935
290
+ django_cfg/core/generation.py,sha256=2lovChgsZXE1q3ut23Ji0VYpm79wOflrK-rCsKM7ulc,23051
291
291
  django_cfg/core/integration.py,sha256=5kzkZSd45ij0rfrBdeNUYnDalObqvK__XpoP31xFYKo,5224
292
292
  django_cfg/core/validation.py,sha256=PhwDBTs24nuM3xqfIT3hXmN88VrhMT-Bk8Yb8FxjmPk,6590
293
293
  django_cfg/management/__init__.py,sha256=NrLAhiS59hqjy-bipOC1abNuRiNm5BpKXmjN05VzKbM,28
@@ -322,7 +322,7 @@ django_cfg/models/api.py,sha256=bCsQR3CVsAUs78m1Q1aFpPTNbvGtr1cq-fuxdCK2-JI,4596
322
322
  django_cfg/models/base.py,sha256=Gy_B2dXSu-lYQjxlCaP6tkngFKhBFkCPeMNIpkkkKSU,10408
323
323
  django_cfg/models/cache.py,sha256=oAiBPM89pZfLlruIzDVFmqNmHdOPk3a2KAgB9jubUPg,12133
324
324
  django_cfg/models/cfg.py,sha256=P6YowmE-VOqp_L25Ijxj2hjjNhB9xtlm8G35DHWqTfk,2702
325
- django_cfg/models/constance.py,sha256=hzO3GuyGk5vFRD7pNWhiQZ7jz_JgFfJ_ry2vsf4108s,6818
325
+ django_cfg/models/constance.py,sha256=BqwoPvUx5vfrZT6qF2KR0prpsSM5VEYIYJUVlB50ewk,8936
326
326
  django_cfg/models/cors.py,sha256=lozVoQJVehhNL1qzOhvAkd4ZpgwAdOJ-OUX7wkJp5W4,3567
327
327
  django_cfg/models/database.py,sha256=LpcmEljjr-2pnR8UVSziUNSnucsojfh8PcgayhrWqK4,16875
328
328
  django_cfg/models/drf.py,sha256=ZzxYv1KjA-iYLRGZj5HUcIyO9tg2B0Gudp1aZz9QNVg,9741
@@ -351,6 +351,8 @@ django_cfg/modules/django_currency/__init__.py,sha256=SLzzYkkqoz9EsspkzEK0yZ4_Q3
351
351
  django_cfg/modules/django_currency/cache.py,sha256=dlrIZN4_436DwTeChbuGOBEUHBobR3dFzCR0J32QN1E,15348
352
352
  django_cfg/modules/django_currency/converter.py,sha256=wC7N_vaxBrUY9jNQQHEsOfAIIvogM0HrPc0UuKOGf9g,11771
353
353
  django_cfg/modules/django_currency/service.py,sha256=bfUTbE4B2KoOcn77uF8EkXbvgEhsIW8opzYpT1ufC3U,9016
354
+ django_cfg/modules/django_import_export/README.md,sha256=OuGT5gv0hwt3dcbMLfZUfostZnXALeN4OifgRvv--4k,2453
355
+ django_cfg/modules/django_import_export/__init__.py,sha256=jPaOqrizOZ9Kl6222IVG6PBb-9oqCMsFN4qVNPHZpUM,1565
354
356
  django_cfg/modules/django_llm/README.md,sha256=31uQG9_z-HroEUevtOPJbZ86H9yiwzZJs0omf-Kwh-o,9374
355
357
  django_cfg/modules/django_llm/__init__.py,sha256=Nirl7Ap3sv5qS5EWM0IEUl_ul-mSYacIz_1plplyM7s,1913
356
358
  django_cfg/modules/django_llm/example.py,sha256=uL3hbRHHuvmWrNzMI7uSV5wrbIck5yqcgrfRGmA76Wg,13066
@@ -396,7 +398,7 @@ django_cfg/modules/django_unfold/models/tabs.py,sha256=AHV7lmaRTjOluf9mgZvXISG5D
396
398
  django_cfg/registry/__init__.py,sha256=q6z9hGcBdtzbVLeDeQtP-A31z-1V7myZqjlZyTs1uo0,540
397
399
  django_cfg/registry/core.py,sha256=lKKcqe4iDqgd42iwL8KNl6kyjtgQ6KWReJMzJ3OqfZo,2257
398
400
  django_cfg/registry/exceptions.py,sha256=b4pIakeRxhT1-ST3lbAnmAQaASRBARCoah_w6vb3VF0,399
399
- django_cfg/registry/modules.py,sha256=DUJ6zVC5k9JGImh85kqx-1mDhI_cKvqErhMciyTdGXk,384
401
+ django_cfg/registry/modules.py,sha256=e8lCG5C-yhRgvs8El_-6Xbdrte-enZF_Xb3B4opO-Hs,1135
400
402
  django_cfg/registry/services.py,sha256=wpGSgSCUr4e9pUh5-rwN1AyPLGazK6KD-Ky4vz-elIw,1219
401
403
  django_cfg/registry/third_party.py,sha256=3VPyh5XkHJr6uDNbpv04HutVSumoyo5jgB-zyqD0jJk,3110
402
404
  django_cfg/routing/__init__.py,sha256=zOg9yh2lP2NaxlnZpVH8IogQBHGlcky_C-n0VWD9LIc,277
@@ -410,6 +412,9 @@ django_cfg/templates/admin/constance/includes/fieldset_header.html,sha256=kAyS0j
410
412
  django_cfg/templates/admin/constance/includes/results_list.html,sha256=OqWyyTuM7iWNjLc1yVp3YHFJk3APxk_Qto0JtssMX2Q,558
411
413
  django_cfg/templates/admin/constance/includes/setting_row.html,sha256=Q4djpNLtZhh_dh_ZoX1PPXN9YUv5AMG49HATErl274o,2601
412
414
  django_cfg/templates/admin/constance/includes/table_headers.html,sha256=_flMPr9mSZOO66Jg0F4OEXlGklRyH-C0_ImfGu-eOLM,677
415
+ django_cfg/templates/admin/import_export/change_list_export.html,sha256=oFBsnpgZ24gV4--UpPRLAqr_kU6-Y3MAudpHQKigKQY,1241
416
+ django_cfg/templates/admin/import_export/change_list_import.html,sha256=jL7Dhjcbx8IfzY-ltlxoWLvF97tD9B77moj8Mh6sRjY,1214
417
+ django_cfg/templates/admin/import_export/change_list_import_export.html,sha256=KWnPbkv_kP5TlAKBRutbk_eFTqPXDt6_SmxXULE94iE,1840
413
418
  django_cfg/templates/admin/layouts/dashboard_with_tabs.html,sha256=ggh2nOYcIxSEkFvniuo-8mixAz13IkfLKXd3NTf7lHQ,18162
414
419
  django_cfg/templates/admin/snippets/components/activity_tracker.html,sha256=WtZyHUmAQwVjvL3PV8OTu5_-FGhTUcPyBUXi8K-c6Eg,692
415
420
  django_cfg/templates/admin/snippets/components/charts_section.html,sha256=SZV2GLkSkYbXaWnUntbwxBhVXJRPHpjNcJrapqv3jO4,1932
@@ -436,8 +441,8 @@ django_cfg/utils/path_resolution.py,sha256=C9As6p4Q9l3VeoVkFDRPQWGrzAWf8O8UxLVka
436
441
  django_cfg/utils/smart_defaults.py,sha256=b6A1z7VO1NJGq0oUQXN5P97c3k_Ssgw6qUi0mK-4TlM,19786
437
442
  django_cfg/utils/toolkit.py,sha256=Td8_iXNaftonF_xdZP4Y3uO65nuA_4_zditn5Q_Pfcw,23310
438
443
  django_cfg/utils/version_check.py,sha256=jI4v3YMdQriUEeb_TvRl511sDghy6I75iKRDUaNpucs,4800
439
- django_cfg-1.2.5.dist-info/METADATA,sha256=NMqpUdKjOVPigv8vWj7V1omQJ3eBFlSEN0lJqAOZqeE,45616
440
- django_cfg-1.2.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
441
- django_cfg-1.2.5.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
442
- django_cfg-1.2.5.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
443
- django_cfg-1.2.5.dist-info/RECORD,,
444
+ django_cfg-1.2.6.dist-info/METADATA,sha256=W8B16hVOMCmDa3_cBQdJboJmVNmpfYpJ99bTqL4UyCo,45616
445
+ django_cfg-1.2.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
446
+ django_cfg-1.2.6.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
447
+ django_cfg-1.2.6.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
448
+ django_cfg-1.2.6.dist-info/RECORD,,