django-cfg 1.2.3__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 +1 -1
- django_cfg/apps/accounts/admin/twilio_response.py +1 -2
- django_cfg/apps/accounts/admin/user.py +6 -1
- django_cfg/apps/accounts/models.py +83 -0
- django_cfg/apps/leads/admin/leads_admin.py +1 -2
- django_cfg/apps/newsletter/admin/newsletter_admin.py +1 -2
- django_cfg/apps/support/admin/support_admin.py +1 -2
- django_cfg/core/generation.py +2 -0
- django_cfg/models/constance.py +52 -5
- django_cfg/modules/django_import_export/README.md +81 -0
- django_cfg/modules/django_import_export/__init__.py +43 -0
- django_cfg/registry/modules.py +10 -0
- django_cfg/templates/admin/import_export/change_list_export.html +24 -0
- django_cfg/templates/admin/import_export/change_list_import.html +24 -0
- django_cfg/templates/admin/import_export/change_list_import_export.html +34 -0
- {django_cfg-1.2.3.dist-info → django_cfg-1.2.6.dist-info}/METADATA +2 -1
- {django_cfg-1.2.3.dist-info → django_cfg-1.2.6.dist-info}/RECORD +20 -15
- {django_cfg-1.2.3.dist-info → django_cfg-1.2.6.dist-info}/WHEEL +0 -0
- {django_cfg-1.2.3.dist-info → django_cfg-1.2.6.dist-info}/entry_points.txt +0 -0
- {django_cfg-1.2.3.dist-info → django_cfg-1.2.6.dist-info}/licenses/LICENSE +0 -0
django_cfg/__init__.py
CHANGED
@@ -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
|
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
|
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
|
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
|
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
|
django_cfg/core/generation.py
CHANGED
@@ -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")
|
django_cfg/models/constance.py
CHANGED
@@ -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.
|
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.
|
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
|
-
|
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
|
+
]
|
django_cfg/registry/modules.py
CHANGED
@@ -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.
|
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
|
@@ -47,6 +47,7 @@ Requires-Dist: django-import-export<5.0,>=4.3.0
|
|
47
47
|
Requires-Dist: django-json-widget<3.0,>=2.0.0
|
48
48
|
Requires-Dist: django-ratelimit<5.0.0,>=4.1.0
|
49
49
|
Requires-Dist: django-redis<7.0,>=6.0.0
|
50
|
+
Requires-Dist: django-revolution<2.0,>=1.0.43
|
50
51
|
Requires-Dist: django-unfold<1.0,>=0.64.0
|
51
52
|
Requires-Dist: djangorestframework-simplejwt<6.0,>=5.5.0
|
52
53
|
Requires-Dist: djangorestframework-simplejwt[token-blacklist]<6.0,>=5.5.0
|
@@ -1,5 +1,5 @@
|
|
1
1
|
django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
django_cfg/__init__.py,sha256=
|
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=
|
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=
|
23
|
-
django_cfg/apps/accounts/admin/user.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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.
|
440
|
-
django_cfg-1.2.
|
441
|
-
django_cfg-1.2.
|
442
|
-
django_cfg-1.2.
|
443
|
-
django_cfg-1.2.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|