django-cfg 1.4.118__py3-none-any.whl → 1.4.119__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of django-cfg might be problematic. Click here for more details.

django_cfg/__init__.py CHANGED
@@ -32,7 +32,7 @@ Example:
32
32
  default_app_config = "django_cfg.apps.DjangoCfgConfig"
33
33
 
34
34
  # Version information
35
- __version__ = "1.4.118"
35
+ __version__ = "1.4.119"
36
36
  __license__ = "MIT"
37
37
 
38
38
  # Import registry for organized lazy loading
@@ -45,6 +45,7 @@ DEFAULT_APPS: List[str] = [
45
45
  # Django CFG Core
46
46
  "django_cfg",
47
47
  "django_cfg.modules.django_client",
48
+ "django_cfg.modules.django_admin",
48
49
  ]
49
50
 
50
51
  # Default middleware stack
@@ -0,0 +1,19 @@
1
+ """
2
+ Django app configuration for django_admin module.
3
+
4
+ This makes django_admin a proper Django app so templates are automatically discovered.
5
+ """
6
+ from django.apps import AppConfig
7
+
8
+
9
+ class DjangoAdminConfig(AppConfig):
10
+ """Configuration for django_admin module."""
11
+
12
+ default_auto_field = "django.db.models.BigAutoField"
13
+ name = "django_cfg.modules.django_admin"
14
+ label = "django_cfg_admin"
15
+ verbose_name = "Django Admin (django-cfg)"
16
+
17
+ def ready(self):
18
+ """Called when Django is ready."""
19
+ pass
@@ -558,12 +558,14 @@ class PydanticAdminMixin:
558
558
  Override form field for specific database field types.
559
559
 
560
560
  Automatically detects and customizes encrypted fields from django-crypto-fields.
561
+ Respects the show_encrypted_fields_as_plain_text setting from AdminConfig.
562
+ Uses custom widgets with copy-to-clipboard functionality.
561
563
  """
562
564
  # Check if this is an EncryptedTextField or EncryptedCharField
563
565
  field_class_name = db_field.__class__.__name__
564
566
  if 'Encrypted' in field_class_name and ('TextField' in field_class_name or 'CharField' in field_class_name):
565
567
  from django import forms
566
- from django.forms.widgets import PasswordInput
568
+ from ..widgets import EncryptedFieldWidget, EncryptedPasswordWidget
567
569
 
568
570
  # Determine placeholder based on field name
569
571
  placeholder = "Enter value"
@@ -574,16 +576,25 @@ class PydanticAdminMixin:
574
576
  elif 'passphrase' in db_field.name.lower():
575
577
  placeholder = "Enter Passphrase (if required)"
576
578
 
577
- # Return CharField with PasswordInput widget for security
578
- # render_value=True shows masked value (••••••) after save
579
+ # Widget attributes
580
+ widget_attrs = {
581
+ 'placeholder': placeholder,
582
+ }
583
+
584
+ # Decide widget based on config
585
+ show_plain_text = getattr(self.config, 'show_encrypted_fields_as_plain_text', False)
586
+
587
+ if show_plain_text:
588
+ # Show as plain text with copy button
589
+ widget = EncryptedFieldWidget(attrs=widget_attrs, show_copy_button=True)
590
+ else:
591
+ # Show as password (masked) with copy button
592
+ # render_value=True shows masked value (••••••) after save
593
+ widget = EncryptedPasswordWidget(attrs=widget_attrs, render_value=True, show_copy_button=True)
594
+
595
+ # Return CharField with appropriate widget
579
596
  return forms.CharField(
580
- widget=PasswordInput(
581
- attrs={
582
- 'placeholder': placeholder,
583
- 'class': 'appearance-none block w-full bg-gray-200 text-gray-700 border border-gray-200 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500'
584
- },
585
- render_value=True # Show masked value after save
586
- ),
597
+ widget=widget,
587
598
  required=not db_field.blank and not db_field.null,
588
599
  help_text=db_field.help_text or "This field is encrypted at rest",
589
600
  label=db_field.verbose_name if hasattr(db_field, 'verbose_name') else db_field.name.replace('_', ' ').title()
@@ -148,6 +148,13 @@ class AdminConfig(BaseModel):
148
148
  description="Markdown documentation configuration"
149
149
  )
150
150
 
151
+ # Encrypted fields options
152
+ show_encrypted_fields_as_plain_text: bool = Field(
153
+ False,
154
+ description="Show encrypted fields (django-crypto-fields) as plain text instead of password masked. "
155
+ "WARNING: This exposes sensitive data in the admin interface. Use only in trusted environments."
156
+ )
157
+
151
158
  def get_display_field_config(self, field_name: str) -> Optional[FieldConfig]:
152
159
  """Get FieldConfig for a specific field."""
153
160
  for field_config in self.display_fields:
@@ -0,0 +1,80 @@
1
+ {% comment %}
2
+ Template for encrypted text field with copy button.
3
+ Based on unfold/widgets/text.html with added copy functionality.
4
+ {% endcomment %}
5
+
6
+ <div class="max-w-2xl relative w-full">
7
+ {% if widget.prefix %}
8
+ <span class="absolute left-3 top-0 bottom-0 flex items-center justify-center">
9
+ {{ widget.prefix }}
10
+ </span>
11
+ {% endif %}
12
+
13
+ {% if widget.prefix_icon %}
14
+ <span class="material-symbols-outlined absolute left-3 top-0 bottom-0 flex items-center justify-center text-base-400 dark:text-base-500">
15
+ {{ widget.prefix_icon }}
16
+ </span>
17
+ {% endif %}
18
+
19
+ {% include "django/forms/widgets/input.html" %}
20
+
21
+ {% if widget.suffix %}
22
+ <span class="absolute right-3 top-0 bottom-0 flex items-center justify-center">
23
+ {{ widget.suffix }}
24
+ </span>
25
+ {% endif %}
26
+
27
+ {% if widget.suffix_icon %}
28
+ <span class="material-symbols-outlined absolute right-3 top-0 bottom-0 flex items-center justify-center text-base-400 dark:text-base-500">
29
+ {{ widget.suffix_icon }}
30
+ </span>
31
+ {% endif %}
32
+
33
+ {% if widget.show_copy_button %}
34
+ <button
35
+ type="button"
36
+ onclick="copyEncryptedField(this)"
37
+ class="material-symbols-outlined absolute right-3 top-0 bottom-0 flex items-center justify-center text-base-400 hover:text-primary-600 dark:text-base-500 dark:hover:text-primary-500 cursor-pointer transition-colors"
38
+ title="Copy to clipboard"
39
+ >
40
+ content_copy
41
+ </button>
42
+ {% endif %}
43
+ </div>
44
+
45
+ <script>
46
+ function copyEncryptedField(button) {
47
+ // Get the input field (previous sibling of button's parent)
48
+ const container = button.parentElement;
49
+ const input = container.querySelector('input');
50
+
51
+ if (!input || !input.value) {
52
+ return;
53
+ }
54
+
55
+ // Copy to clipboard
56
+ navigator.clipboard.writeText(input.value).then(() => {
57
+ // Visual feedback - change icon temporarily
58
+ const originalIcon = button.textContent;
59
+ button.textContent = 'check';
60
+ button.classList.add('text-green-600', 'dark:text-green-500');
61
+
62
+ // Reset after 2 seconds
63
+ setTimeout(() => {
64
+ button.textContent = originalIcon;
65
+ button.classList.remove('text-green-600', 'dark:text-green-500');
66
+ }, 2000);
67
+ }).catch(err => {
68
+ console.error('Failed to copy:', err);
69
+ // Show error feedback
70
+ const originalIcon = button.textContent;
71
+ button.textContent = 'error';
72
+ button.classList.add('text-red-600', 'dark:text-red-500');
73
+
74
+ setTimeout(() => {
75
+ button.textContent = originalIcon;
76
+ button.classList.remove('text-red-600', 'dark:text-red-500');
77
+ }, 2000);
78
+ });
79
+ }
80
+ </script>
@@ -0,0 +1,62 @@
1
+ {% comment %}
2
+ Template for encrypted password field with copy button.
3
+ Based on Django's default password widget with Unfold styling and copy button.
4
+ {% endcomment %}
5
+
6
+ <div class="max-w-2xl relative w-full">
7
+ {% include "django/forms/widgets/input.html" %}
8
+
9
+ {% if widget.show_copy_button %}
10
+ <button
11
+ type="button"
12
+ onclick="copyEncryptedPassword(this)"
13
+ class="material-symbols-outlined absolute right-3 top-0 bottom-0 flex items-center justify-center text-base-400 hover:text-primary-600 dark:text-base-500 dark:hover:text-primary-500 cursor-pointer transition-colors"
14
+ title="Copy to clipboard"
15
+ >
16
+ content_copy
17
+ </button>
18
+ {% endif %}
19
+ </div>
20
+
21
+ <script>
22
+ function copyEncryptedPassword(button) {
23
+ // Get the input field (previous sibling of button's parent)
24
+ const container = button.parentElement;
25
+ const input = container.querySelector('input');
26
+
27
+ if (!input || !input.value) {
28
+ return;
29
+ }
30
+
31
+ // For password fields, we need to temporarily change type to text to get the real value
32
+ const originalType = input.type;
33
+ input.type = 'text';
34
+ const value = input.value;
35
+ input.type = originalType;
36
+
37
+ // Copy to clipboard
38
+ navigator.clipboard.writeText(value).then(() => {
39
+ // Visual feedback - change icon temporarily
40
+ const originalIcon = button.textContent;
41
+ button.textContent = 'check';
42
+ button.classList.add('text-green-600', 'dark:text-green-500');
43
+
44
+ // Reset after 2 seconds
45
+ setTimeout(() => {
46
+ button.textContent = originalIcon;
47
+ button.classList.remove('text-green-600', 'dark:text-green-500');
48
+ }, 2000);
49
+ }).catch(err => {
50
+ console.error('Failed to copy:', err);
51
+ // Show error feedback
52
+ const originalIcon = button.textContent;
53
+ button.textContent = 'error';
54
+ button.classList.add('text-red-600', 'dark:text-red-500');
55
+
56
+ setTimeout(() => {
57
+ button.textContent = originalIcon;
58
+ button.classList.remove('text-red-600', 'dark:text-red-500');
59
+ }, 2000);
60
+ });
61
+ }
62
+ </script>
@@ -2,8 +2,11 @@
2
2
  Widget system for Django Admin.
3
3
  """
4
4
 
5
+ from .encrypted_field_widget import EncryptedFieldWidget, EncryptedPasswordWidget
5
6
  from .registry import WidgetRegistry
6
7
 
7
8
  __all__ = [
8
9
  "WidgetRegistry",
10
+ "EncryptedFieldWidget",
11
+ "EncryptedPasswordWidget",
9
12
  ]
@@ -0,0 +1,66 @@
1
+ """
2
+ Custom widget for encrypted fields with copy button.
3
+ """
4
+ from typing import Any, Optional
5
+
6
+ from unfold.widgets import UnfoldAdminPasswordInput, UnfoldAdminTextInputWidget
7
+
8
+
9
+ class EncryptedFieldWidget(UnfoldAdminTextInputWidget):
10
+ """
11
+ Text input widget for encrypted fields with copy-to-clipboard button.
12
+
13
+ Extends UnfoldAdminTextInputWidget to add a copy button on the right side.
14
+ """
15
+
16
+ template_name = "django_admin/widgets/encrypted_field.html"
17
+
18
+ def __init__(self, attrs: Optional[dict[str, Any]] = None, show_copy_button: bool = True) -> None:
19
+ """
20
+ Initialize the widget.
21
+
22
+ Args:
23
+ attrs: Widget attributes
24
+ show_copy_button: Whether to show the copy button (default: True)
25
+ """
26
+ self.show_copy_button = show_copy_button
27
+ super().__init__(attrs=attrs)
28
+
29
+ def get_context(self, name, value, attrs):
30
+ """Add copy button context."""
31
+ context = super().get_context(name, value, attrs)
32
+ context['widget']['show_copy_button'] = self.show_copy_button
33
+ return context
34
+
35
+
36
+ class EncryptedPasswordWidget(UnfoldAdminPasswordInput):
37
+ """
38
+ Password input widget for encrypted fields with copy button.
39
+
40
+ Extends UnfoldAdminPasswordInput to add a copy button on the right side.
41
+ """
42
+
43
+ template_name = "django_admin/widgets/encrypted_password.html"
44
+
45
+ def __init__(
46
+ self,
47
+ attrs: Optional[dict[str, Any]] = None,
48
+ render_value: bool = False,
49
+ show_copy_button: bool = True
50
+ ) -> None:
51
+ """
52
+ Initialize the widget.
53
+
54
+ Args:
55
+ attrs: Widget attributes
56
+ render_value: Whether to render the value (default: False)
57
+ show_copy_button: Whether to show the copy button (default: True)
58
+ """
59
+ self.show_copy_button = show_copy_button
60
+ super().__init__(attrs=attrs, render_value=render_value)
61
+
62
+ def get_context(self, name, value, attrs):
63
+ """Add copy button context."""
64
+ context = super().get_context(name, value, attrs)
65
+ context['widget']['show_copy_button'] = self.show_copy_button
66
+ return context
django_cfg/pyproject.toml CHANGED
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "django-cfg"
7
- version = "1.4.118"
7
+ version = "1.4.119"
8
8
  description = "Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features."
9
9
  readme = "README.md"
10
10
  keywords = [ "django", "configuration", "pydantic", "settings", "type-safety", "pydantic-settings", "django-environ", "startup-validation", "ide-autocomplete", "nextjs-admin", "react-admin", "websocket", "centrifugo", "real-time", "typescript-generation", "ai-agents", "enterprise-django", "django-settings", "type-safe-config", "modern-django",]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: django-cfg
3
- Version: 1.4.118
3
+ Version: 1.4.119
4
4
  Summary: Modern Django framework with type-safe Pydantic v2 configuration, Next.js admin integration, real-time WebSockets, and 8 enterprise apps. Replace settings.py with validated models, 90% less code. Production-ready with AI agents, auto-generated TypeScript clients, and zero-config features.
5
5
  Project-URL: Homepage, https://djangocfg.com
6
6
  Project-URL: Documentation, https://djangocfg.com
@@ -1,5 +1,5 @@
1
1
  django_cfg/README.md,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- django_cfg/__init__.py,sha256=czBPTVeDvyLUMK-04V3RRLhBFzXwK7DP_dDyzQq7ZNw,1621
2
+ django_cfg/__init__.py,sha256=H3Lu0mvpULyWtMRq04fjixa209x5dcO9YdaHFessd4Q,1621
3
3
  django_cfg/apps.py,sha256=72m3uuvyqGiLx6gOfE-BD3P61jddCCERuBOYpxTX518,1605
4
4
  django_cfg/config.py,sha256=xdwFE8bocOEnMjqDOwr1_M02oUgdaMG_2M6F_IuB9GQ,1351
5
5
  django_cfg/apps/__init__.py,sha256=JtDmEYt1OcleWM2ZaeX0LKDnRQzPOavfaXBWG4ECB5Q,26
@@ -536,7 +536,7 @@ django_cfg/cli/commands/create_project.py,sha256=cENwRIG7zX_95lY7Kt_xKGULZWqfwni
536
536
  django_cfg/cli/commands/info.py,sha256=JNLt9gUTZopR-D7FUDIeEyOQR9-2LTpHntHi_h-7Mho,4794
537
537
  django_cfg/core/__init__.py,sha256=bZ3hgN9SX6l3DXEN-cMyOGwwXMu4UFkWyR0ds_yEnVs,1784
538
538
  django_cfg/core/config.py,sha256=0xwXf0cPiRGM8paUPXjECHdYqwuRLy4WkunavWl9Igw,679
539
- django_cfg/core/constants.py,sha256=ool-h1MXDtgRKj8-e8aYcM6XY_Uzy1dgx-xLy0gsk10,2686
539
+ django_cfg/core/constants.py,sha256=D3-9XIMpwoYDgye7P_ixurS1IzV3R4fUvmSclXo8uf4,2725
540
540
  django_cfg/core/exceptions.py,sha256=-jHOxN_X_k9BGI50zBLloVawCMe-uIruiyLHto12B-k,2215
541
541
  django_cfg/core/validation.py,sha256=QmwGlNDa0MFG2OUmgykIUAaEotT55YNh-wAWSVxOAos,6165
542
542
  django_cfg/core/backends/__init__.py,sha256=5Qfza7oKQ8_UIHOs4ibhYvwtgAjngUqLrlwjKl_q124,38
@@ -675,12 +675,13 @@ django_cfg/models/tasks/utils.py,sha256=9TEbdxgd0N_O2T_7GGwkyPeDg4H7tSKLHoHG_n8e
675
675
  django_cfg/modules/__init__.py,sha256=Ip9WMpzImEwIAywpFwU056_v0O9oIGG7nCT1YSArxkw,316
676
676
  django_cfg/modules/base.py,sha256=Grmgxc5dvnAEM1sudWEWO4kv8L0Ks-y32nxTk2vwdjQ,6272
677
677
  django_cfg/modules/django_admin/__init__.py,sha256=ncTMbxR7ccVd5xS-sZE_yJODjVMFq8HDFaDnP6lyvIg,3328
678
+ django_cfg/modules/django_admin/apps.py,sha256=xJjgIRgS_I1ehyq7ZbFpZY_L4umRa5ZPQP3mf0alUaU,526
678
679
  django_cfg/modules/django_admin/base/__init__.py,sha256=tzre09bnD_SlS-pA30WzYZRxyvch7eLq3q0wLEcZOmc,118
679
- django_cfg/modules/django_admin/base/pydantic_admin.py,sha256=6tB_8hZLT3ZzwUu6rlvzhkQ_BkDq8niaTE3TIa0IcgM,24977
680
+ django_cfg/modules/django_admin/base/pydantic_admin.py,sha256=xewt_ld40NntdjtZ-k-VwinhfDkIRk71nwu5DVDQzeQ,25364
680
681
  django_cfg/modules/django_admin/base/unfold_admin.py,sha256=iqpRWSkzW5HktXDuuG7G3J6RoIfW48dWPMJTa7Yk08g,729
681
682
  django_cfg/modules/django_admin/config/__init__.py,sha256=HDuJxhAS27EiL1pXLNvMePREB2gfoS2i_0Ur1ITCjAM,926
682
683
  django_cfg/modules/django_admin/config/action_config.py,sha256=JjS01JxLT-FzUVq7RlKaB7L38wmVL8uibXO_iXZcljo,1668
683
- django_cfg/modules/django_admin/config/admin_config.py,sha256=TnPI-kLZj6uoIH7opCD70HQ6I_yJ7jPKnphS0h9P42s,5242
684
+ django_cfg/modules/django_admin/config/admin_config.py,sha256=L48YHLt-JyNyL-XOltqIZVh1ALoG4wXQsvi_WIbhuFw,5577
684
685
  django_cfg/modules/django_admin/config/background_task_config.py,sha256=7-8B1rhpeafanVxtjFQUx0mVjcA5xmxZIxqKzaBwMX0,1760
685
686
  django_cfg/modules/django_admin/config/documentation_config.py,sha256=lI_gMSWCtyKmdyttLNdgbg_zbGgrwXA-QoLxVOXJj9A,14189
686
687
  django_cfg/modules/django_admin/config/field_config.py,sha256=LeHoumm-lmiYIu0dBmoyCdTkddQdcv20_KrD3WRhkQ0,11743
@@ -699,6 +700,8 @@ django_cfg/modules/django_admin/templates/django_admin/change_form_docs.html,sha
699
700
  django_cfg/modules/django_admin/templates/django_admin/change_list_docs.html,sha256=MfH6mf9v6E3y97TjvjvZ2A7RMhOkKd6CtxEw3tPV5WE,802
700
701
  django_cfg/modules/django_admin/templates/django_admin/documentation_block.html,sha256=fDUZYDWuB68NOm4fjTr0OLfqG2m-UpE-MZL1upkUNHc,14174
701
702
  django_cfg/modules/django_admin/templates/django_admin/markdown_docs_block.html,sha256=nO9oEyDYozYF-euaLzE0Cn_Yo_LGUlta-BsRgShDG10,1992
703
+ django_cfg/modules/django_admin/templates/django_admin/widgets/encrypted_field.html,sha256=-Kd4twY0sav2M5x_0oDj8ElA7CBccToVHFiwGa2WF-w,2774
704
+ django_cfg/modules/django_admin/templates/django_admin/widgets/encrypted_password.html,sha256=BdiM0CqRyBH1aHGf6iLSfSKOoADY5qaqetbC9AktzaI,2154
702
705
  django_cfg/modules/django_admin/utils/CODE_BLOCK_DOCS.md,sha256=rp5qMG-Ci30fIs6EyZctjEbhQwxfNq9e36B4CTZOnR0,9456
703
706
  django_cfg/modules/django_admin/utils/__init__.py,sha256=5V1Og6fpIpRqDIoqF7jYnBmPl9TjV5kByghzT6iOpPs,745
704
707
  django_cfg/modules/django_admin/utils/badges.py,sha256=eZ1UThdwvv2cHAIDc4vTrD5xAet7fmeb9h9yj4ZXJ-c,6328
@@ -707,7 +710,8 @@ django_cfg/modules/django_admin/utils/displays.py,sha256=f-FT1mD-X56X6xLDJ9FuCi4
707
710
  django_cfg/modules/django_admin/utils/html_builder.py,sha256=E0ysbbImpZqSr7YFw3FYryG0jjJfffIOqFzefk-HMl8,14500
708
711
  django_cfg/modules/django_admin/utils/markdown_renderer.py,sha256=eMYde8cDo9y5CO5qNjy7juYe_OPpSpFB1-d84ylpbk4,14324
709
712
  django_cfg/modules/django_admin/utils/mermaid_plugin.py,sha256=37x_0FQE5IyR6TiaDZDrQQHeQmAsPtlZBnq5N8eAKqA,8889
710
- django_cfg/modules/django_admin/widgets/__init__.py,sha256=mmPw5FMYR21GDGFMr-MOCcdM4G2_ZR60ClInHjdnTBE,115
713
+ django_cfg/modules/django_admin/widgets/__init__.py,sha256=SVVytNURG_TlWePwhws9FYeDe_xp4Ob_CYVA88Y08es,256
714
+ django_cfg/modules/django_admin/widgets/encrypted_field_widget.py,sha256=h4bSAI2sLjKuBFDufWhtQQQ-eMIAqUzsUezi1p0ERuM,2146
711
715
  django_cfg/modules/django_admin/widgets/registry.py,sha256=q0Yyaze5ZTYLJslPyX9e4Few_FGLnGBQwtNln9Okyt4,5610
712
716
  django_cfg/modules/django_client/__init__.py,sha256=iHaGKbsyR2wMmVCWNsETC7cwB60fZudvnFMiK1bchW8,529
713
717
  django_cfg/modules/django_client/apps.py,sha256=xfkw2aXy08xXlkFhbCiTFveMmRwlDk3SQOAWdqXraFM,1952
@@ -1066,9 +1070,9 @@ django_cfg/utils/version_check.py,sha256=WO51J2m2e-wVqWCRwbultEwu3q1lQasV67Mw2aa
1066
1070
  django_cfg/CHANGELOG.md,sha256=jtT3EprqEJkqSUh7IraP73vQ8PmKUMdRtznQsEnqDZk,2052
1067
1071
  django_cfg/CONTRIBUTING.md,sha256=DU2kyQ6PU0Z24ob7O_OqKWEYHcZmJDgzw-lQCmu6uBg,3041
1068
1072
  django_cfg/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1069
- django_cfg/pyproject.toml,sha256=fZ9FGyvoUZbCwaNqWJDQwUNYeN11UYgds7UsrzwGFO0,8665
1070
- django_cfg-1.4.118.dist-info/METADATA,sha256=NcD294dwA8ckrblk-0er6UcqtHdYYren4RsZh77BqkU,23876
1071
- django_cfg-1.4.118.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1072
- django_cfg-1.4.118.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1073
- django_cfg-1.4.118.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1074
- django_cfg-1.4.118.dist-info/RECORD,,
1073
+ django_cfg/pyproject.toml,sha256=bhPs3HhPDoIc56W0TLwHYE5Ekh1zHRrPX_5o8IoncAU,8665
1074
+ django_cfg-1.4.119.dist-info/METADATA,sha256=qCVV9288Nf1L4WQUHvVb74viHrUEZ-Q-pmRLDuTl9kM,23876
1075
+ django_cfg-1.4.119.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
1076
+ django_cfg-1.4.119.dist-info/entry_points.txt,sha256=Ucmde4Z2wEzgb4AggxxZ0zaYDb9HpyE5blM3uJ0_VNg,56
1077
+ django_cfg-1.4.119.dist-info/licenses/LICENSE,sha256=xHuytiUkSZCRG3N11nk1X6q1_EGQtv6aL5O9cqNRhKE,1071
1078
+ django_cfg-1.4.119.dist-info/RECORD,,