django-cfg 1.3.9__py3-none-any.whl → 1.3.13__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.
Files changed (188) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/accounts/admin/inlines.py +11 -5
  3. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  4. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  5. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  13. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  14. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  15. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  16. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  17. django_cfg/apps/payments/config/__init__.py +14 -15
  18. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  19. django_cfg/apps/payments/config/helpers.py +8 -13
  20. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  21. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  22. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  23. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  24. django_cfg/apps/payments/models/payments.py +94 -0
  25. django_cfg/apps/payments/services/core/base.py +4 -4
  26. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  27. django_cfg/apps/payments/services/providers/base.py +209 -3
  28. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  29. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  31. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  32. django_cfg/apps/payments/services/providers/registry.py +5 -5
  33. django_cfg/apps/payments/services/types/requests.py +19 -7
  34. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  35. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  36. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  37. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  38. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  39. django_cfg/apps/payments/urls.py +3 -2
  40. django_cfg/apps/payments/views/api/currencies.py +3 -0
  41. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  42. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  43. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  44. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  45. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  47. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  52. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  53. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  54. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  55. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  56. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  57. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  58. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  59. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  60. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  61. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  62. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  63. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  66. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  67. django_cfg/apps/tasks/urls.py +2 -2
  68. django_cfg/apps/tasks/urls_admin.py +2 -2
  69. django_cfg/apps/tasks/utils/__init__.py +1 -0
  70. django_cfg/apps/tasks/utils/simulator.py +356 -0
  71. django_cfg/apps/tasks/views/__init__.py +16 -0
  72. django_cfg/apps/tasks/views/api.py +569 -0
  73. django_cfg/apps/tasks/views/dashboard.py +58 -0
  74. django_cfg/core/integration/__init__.py +21 -0
  75. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  76. django_cfg/models/constance.py +0 -11
  77. django_cfg/models/payments.py +137 -3
  78. django_cfg/modules/django_tasks.py +54 -21
  79. django_cfg/registry/core.py +4 -9
  80. django_cfg/template_archive/django_sample.zip +0 -0
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/METADATA +2 -2
  82. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/RECORD +85 -153
  83. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  84. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  85. django_cfg/apps/payments/config/constance/fields.py +0 -69
  86. django_cfg/apps/payments/config/constance/settings.py +0 -160
  87. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  88. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  89. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  90. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  91. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  92. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  93. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  94. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  95. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  96. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  97. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  98. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  99. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  100. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  101. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  102. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  103. django_cfg/apps/tasks/views.py +0 -461
  104. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  105. django_cfg/management/commands/app_agent_generate.py +0 -342
  106. django_cfg/management/commands/app_agent_info.py +0 -308
  107. django_cfg/management/commands/auto_generate.py +0 -486
  108. django_cfg/modules/django_app_agent/__init__.py +0 -87
  109. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  110. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  111. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  112. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  113. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  114. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  119. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  120. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  121. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  122. django_cfg/modules/django_app_agent/core/config.py +0 -300
  123. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  124. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  125. django_cfg/modules/django_app_agent/models/base.py +0 -283
  126. django_cfg/modules/django_app_agent/models/context.py +0 -496
  127. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  128. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  129. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  130. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  131. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  132. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  133. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  134. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  135. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  136. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  137. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  138. django_cfg/modules/django_app_agent/services/base.py +0 -437
  139. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  140. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  141. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  142. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  143. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  144. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  145. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  146. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  147. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  148. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  149. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  150. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  151. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  152. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  153. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  154. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  155. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  156. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  157. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  158. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  159. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  160. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  161. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  171. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  172. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  173. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  174. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  175. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  176. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  177. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  178. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  179. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  180. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  181. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  182. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  183. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  184. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  185. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/WHEEL +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/entry_points.txt +0 -0
  188. {django_cfg-1.3.9.dist-info → django_cfg-1.3.13.dist-info}/licenses/LICENSE +0 -0
@@ -1,44 +0,0 @@
1
- """
2
- Django-CFG configuration for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django_cfg.config import BaseCfgConfig
8
- from pydantic import Field
9
- from typing import Optional, List
10
-
11
-
12
- class {{ app_name|pascal_case }}Config(BaseCfgConfig):
13
- """Configuration for {{ app_name }} application."""
14
-
15
- # Basic settings
16
- enabled: bool = Field(default=True, description="Enable {{ app_name }} functionality")
17
- debug_mode: bool = Field(default=False, description="Enable debug mode for {{ app_name }}")
18
-
19
- # Feature toggles
20
- {% if features.api %}
21
- api_enabled: bool = Field(default=True, description="Enable API endpoints")
22
- api_rate_limit: int = Field(default=100, description="API rate limit per hour")
23
- {% endif %}
24
-
25
- {% if features.caching %}
26
- cache_timeout: int = Field(default=300, description="Cache timeout in seconds")
27
- cache_key_prefix: str = Field(default="{{ app_name }}", description="Cache key prefix")
28
- {% endif %}
29
-
30
- {% if features.notifications %}
31
- notifications_enabled: bool = Field(default=True, description="Enable notifications")
32
- email_notifications: bool = Field(default=False, description="Send email notifications")
33
- {% endif %}
34
-
35
- # Business logic settings
36
- max_items_per_user: Optional[int] = Field(default=None, description="Maximum items per user")
37
- allowed_file_types: List[str] = Field(
38
- default=["jpg", "png", "pdf"],
39
- description="Allowed file upload types"
40
- )
41
-
42
- class Meta:
43
- app_name = "{{ app_name }}"
44
- config_prefix = "{{ app_name|upper }}"
@@ -1,81 +0,0 @@
1
- """
2
- Django-CFG module for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django_cfg.modules import BaseCfgModule
8
- from django_cfg.decorators import cfg_module
9
- from .config import {{ app_name|pascal_case }}Config
10
-
11
-
12
- @cfg_module
13
- class {{ app_name|pascal_case }}Module(BaseCfgModule[{{ app_name|pascal_case }}Config]):
14
- """Django-CFG module for {{ app_name }}."""
15
-
16
- config_class = {{ app_name|pascal_case }}Config
17
-
18
- def __init__(self):
19
- """Initialize {{ app_name }} module."""
20
- super().__init__()
21
- self.name = "{{ app_name }}"
22
- self.version = "1.0.0"
23
- self.description = "{{ description }}"
24
-
25
- async def initialize(self):
26
- """Initialize module resources."""
27
- self.logger.info(f"Initializing {{ app_name }} module")
28
-
29
- {% if features.database_setup %}
30
- # Setup database connections if needed
31
- await self._setup_database()
32
- {% endif %}
33
-
34
- {% if features.cache_setup %}
35
- # Setup cache if needed
36
- await self._setup_cache()
37
- {% endif %}
38
-
39
- self.logger.info(f"{{ app_name|title_case }} module initialized successfully")
40
-
41
- async def cleanup(self):
42
- """Cleanup module resources."""
43
- self.logger.info(f"Cleaning up {{ app_name }} module")
44
-
45
- {% if features.cleanup_tasks %}
46
- # Perform cleanup tasks
47
- await self._cleanup_resources()
48
- {% endif %}
49
-
50
- def get_health_status(self) -> dict:
51
- """Get module health status."""
52
- return {
53
- "status": "healthy",
54
- "module": self.name,
55
- "version": self.version,
56
- "config_loaded": self.config is not None,
57
- {% if features.database_setup %}
58
- "database_connected": self._check_database_connection(),
59
- {% endif %}
60
- }
61
-
62
- {% if features.database_setup %}
63
- async def _setup_database(self):
64
- """Setup database connections."""
65
- # Implement database setup logic
66
- pass
67
- {% endif %}
68
-
69
- {% if features.cache_setup %}
70
- async def _setup_cache(self):
71
- """Setup cache connections."""
72
- # Implement cache setup logic
73
- pass
74
- {% endif %}
75
-
76
- {% if features.cleanup_tasks %}
77
- async def _cleanup_resources(self):
78
- """Cleanup module resources."""
79
- # Implement cleanup logic
80
- pass
81
- {% endif %}
@@ -1,107 +0,0 @@
1
- """
2
- Forms for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django import forms
8
- from django.core.exceptions import ValidationError
9
- {% if features.crispy_forms %}
10
- from crispy_forms.helper import FormHelper
11
- from crispy_forms.layout import Layout, Submit, Row, Column
12
- {% endif %}
13
- from .models import {{ app_name|pascal_case }}Model
14
-
15
-
16
- class {{ app_name|pascal_case }}Form(forms.ModelForm):
17
- """Form for {{ app_name }} model."""
18
-
19
- class Meta:
20
- model = {{ app_name|pascal_case }}Model
21
- fields = [
22
- 'name',
23
- 'description',
24
- {% if features.status_tracking %}'status',{% endif %}
25
- ]
26
- widgets = {
27
- 'description': forms.Textarea(attrs={'rows': 4}),
28
- {% if features.status_tracking %}
29
- 'status': forms.Select(attrs={'class': 'form-select'}),
30
- {% endif %}
31
- }
32
- help_texts = {
33
- 'name': 'Enter a descriptive name for this {{ app_name|singular }}',
34
- 'description': 'Provide additional details (optional)',
35
- }
36
-
37
- {% if features.crispy_forms %}
38
- def __init__(self, *args, **kwargs):
39
- super().__init__(*args, **kwargs)
40
- self.helper = FormHelper()
41
- self.helper.layout = Layout(
42
- Row(
43
- Column('name', css_class='form-group col-md-8 mb-0'),
44
- {% if features.status_tracking %}
45
- Column('status', css_class='form-group col-md-4 mb-0'),
46
- {% endif %}
47
- css_class='form-row'
48
- ),
49
- 'description',
50
- Submit('submit', 'Save {{ app_name|title_case }}', css_class='btn btn-primary')
51
- )
52
- {% endif %}
53
-
54
- def clean_name(self):
55
- """Validate name field."""
56
- name = self.cleaned_data.get('name')
57
- if name:
58
- # Check for duplicate names (case-insensitive)
59
- existing = {{ app_name|pascal_case }}Model.objects.filter(
60
- name__iexact=name
61
- )
62
- if self.instance.pk:
63
- existing = existing.exclude(pk=self.instance.pk)
64
-
65
- if existing.exists():
66
- raise ValidationError(
67
- f'A {{ app_name|singular }} with this name already exists.'
68
- )
69
-
70
- return name
71
-
72
- def clean(self):
73
- """Additional form validation."""
74
- cleaned_data = super().clean()
75
-
76
- # Add any cross-field validation here
77
- name = cleaned_data.get('name')
78
- description = cleaned_data.get('description')
79
-
80
- if name and description and name.lower() in description.lower():
81
- self.add_error('description',
82
- 'Description should not just repeat the name.')
83
-
84
- return cleaned_data
85
-
86
-
87
- {% if features.search_forms %}
88
- class {{ app_name|pascal_case }}SearchForm(forms.Form):
89
- """Search form for {{ app_name }}."""
90
-
91
- query = forms.CharField(
92
- max_length=100,
93
- required=False,
94
- widget=forms.TextInput(attrs={
95
- 'placeholder': 'Search {{ app_name|plural }}...',
96
- 'class': 'form-control'
97
- })
98
- )
99
-
100
- {% if features.status_tracking %}
101
- status = forms.ChoiceField(
102
- choices=[('', 'All')] + {{ app_name|pascal_case }}Model.STATUS_CHOICES,
103
- required=False,
104
- widget=forms.Select(attrs={'class': 'form-select'})
105
- )
106
- {% endif %}
107
- {% endif %}
@@ -1,139 +0,0 @@
1
- """
2
- Models for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django.db import models
8
- from django.urls import reverse
9
- from django.core.validators import MinLengthValidator, MaxLengthValidator
10
- {% if app_type == 'django_cfg' %}
11
- from django_cfg.models import BaseCfgModel
12
- {% endif %}
13
- {% if features.user_relations %}
14
- from django.contrib.auth.models import User
15
- {% endif %}
16
- {% if features.uuid_primary_keys %}
17
- import uuid
18
- {% endif %}
19
-
20
-
21
- {% if app_type == 'django_cfg' %}
22
- class {{ app_name|pascal_case }}Model(BaseCfgModel):
23
- {% else %}
24
- class {{ app_name|pascal_case }}Model(models.Model):
25
- {% endif %}
26
- """Main model for {{ app_name }} application."""
27
-
28
- {% if features.uuid_primary_keys %}
29
- id = models.UUIDField(
30
- primary_key=True,
31
- default=uuid.uuid4,
32
- editable=False,
33
- help_text="Unique identifier"
34
- )
35
- {% endif %}
36
-
37
- name = models.CharField(
38
- max_length=100,
39
- validators=[MinLengthValidator(2)],
40
- help_text="Name of the {{ app_name|singular|title_case }}"
41
- )
42
-
43
- description = models.TextField(
44
- blank=True,
45
- help_text="Detailed description"
46
- )
47
-
48
- {% if features.status_tracking %}
49
- STATUS_CHOICES = [
50
- ('draft', 'Draft'),
51
- ('published', 'Published'),
52
- ('archived', 'Archived'),
53
- ]
54
-
55
- status = models.CharField(
56
- max_length=20,
57
- choices=STATUS_CHOICES,
58
- default='draft',
59
- help_text="Current status"
60
- )
61
- {% endif %}
62
-
63
- {% if features.user_relations %}
64
- owner = models.ForeignKey(
65
- User,
66
- on_delete=models.CASCADE,
67
- related_name="{{ app_name }}_owned",
68
- help_text="Owner of this {{ app_name|singular }}"
69
- )
70
- {% endif %}
71
-
72
- {% if not app_type == 'django_cfg' %}
73
- created_at = models.DateTimeField(auto_now_add=True)
74
- updated_at = models.DateTimeField(auto_now=True)
75
- {% endif %}
76
-
77
- class Meta:
78
- verbose_name = "{{ app_name|singular|title_case }}"
79
- verbose_name_plural = "{{ app_name|plural|title_case }}"
80
- ordering = ['-created_at']
81
- {% if features.database_indexes %}
82
- indexes = [
83
- models.Index(fields=['name']),
84
- models.Index(fields=['created_at']),
85
- {% if features.status_tracking %}
86
- models.Index(fields=['status']),
87
- {% endif %}
88
- ]
89
- {% endif %}
90
-
91
- def __str__(self):
92
- return self.name
93
-
94
- def get_absolute_url(self):
95
- return reverse('{{ app_name }}:detail', kwargs={'pk': self.pk})
96
-
97
- {% if features.custom_methods %}
98
- def is_published(self):
99
- """Check if the item is published."""
100
- {% if features.status_tracking %}
101
- return self.status == 'published'
102
- {% else %}
103
- return True
104
- {% endif %}
105
-
106
- def get_display_name(self):
107
- """Get formatted display name."""
108
- return self.name.title()
109
- {% endif %}
110
-
111
-
112
- {% if features.related_models %}
113
- class {{ app_name|pascal_case }}Category(models.Model):
114
- """Category model for {{ app_name }}."""
115
-
116
- name = models.CharField(max_length=50, unique=True)
117
- slug = models.SlugField(unique=True)
118
- description = models.TextField(blank=True)
119
-
120
- class Meta:
121
- verbose_name_plural = "Categories"
122
- ordering = ['name']
123
-
124
- def __str__(self):
125
- return self.name
126
-
127
-
128
- class {{ app_name|pascal_case }}Tag(models.Model):
129
- """Tag model for {{ app_name }}."""
130
-
131
- name = models.CharField(max_length=30, unique=True)
132
- color = models.CharField(max_length=7, default='#007bff') # Hex color
133
-
134
- class Meta:
135
- ordering = ['name']
136
-
137
- def __str__(self):
138
- return self.name
139
- {% endif %}
@@ -1,91 +0,0 @@
1
- """
2
- DRF Serializers for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from rest_framework import serializers
8
- {% if features.nested_serializers %}
9
- from rest_framework.fields import SerializerMethodField
10
- {% endif %}
11
- from .models import {{ app_name|pascal_case }}Model
12
- {% if features.related_models %}
13
- from .models import {{ app_name|pascal_case }}Category, {{ app_name|pascal_case }}Tag
14
- {% endif %}
15
-
16
-
17
- class {{ app_name|pascal_case }}Serializer(serializers.ModelSerializer):
18
- """Serializer for {{ app_name }} model."""
19
-
20
- {% if features.computed_fields %}
21
- display_name = serializers.SerializerMethodField()
22
- is_published = serializers.SerializerMethodField()
23
- {% endif %}
24
-
25
- class Meta:
26
- model = {{ app_name|pascal_case }}Model
27
- fields = [
28
- 'id',
29
- 'name',
30
- 'description',
31
- {% if features.status_tracking %}'status',{% endif %}
32
- {% if features.user_relations %}'owner',{% endif %}
33
- 'created_at',
34
- 'updated_at',
35
- {% if features.computed_fields %}
36
- 'display_name',
37
- 'is_published',
38
- {% endif %}
39
- ]
40
- read_only_fields = ['id', 'created_at', 'updated_at']
41
-
42
- {% if features.computed_fields %}
43
- def get_display_name(self, obj):
44
- """Get formatted display name."""
45
- return obj.get_display_name()
46
-
47
- def get_is_published(self, obj):
48
- """Check if item is published."""
49
- return obj.is_published()
50
- {% endif %}
51
-
52
- def validate_name(self, value):
53
- """Validate name field."""
54
- if len(value.strip()) < 2:
55
- raise serializers.ValidationError(
56
- "Name must be at least 2 characters long."
57
- )
58
- return value.strip()
59
-
60
-
61
- {% if features.list_serializers %}
62
- class {{ app_name|pascal_case }}ListSerializer(serializers.ModelSerializer):
63
- """Lightweight serializer for {{ app_name }} lists."""
64
-
65
- class Meta:
66
- model = {{ app_name|pascal_case }}Model
67
- fields = [
68
- 'id',
69
- 'name',
70
- {% if features.status_tracking %}'status',{% endif %}
71
- 'created_at'
72
- ]
73
- {% endif %}
74
-
75
-
76
- {% if features.related_models %}
77
- class {{ app_name|pascal_case }}CategorySerializer(serializers.ModelSerializer):
78
- """Serializer for {{ app_name }} categories."""
79
-
80
- class Meta:
81
- model = {{ app_name|pascal_case }}Category
82
- fields = ['id', 'name', 'slug', 'description']
83
-
84
-
85
- class {{ app_name|pascal_case }}TagSerializer(serializers.ModelSerializer):
86
- """Serializer for {{ app_name }} tags."""
87
-
88
- class Meta:
89
- model = {{ app_name|pascal_case }}Tag
90
- fields = ['id', 'name', 'color']
91
- {% endif %}
@@ -1,195 +0,0 @@
1
- """
2
- Tests for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django.test import TestCase, Client
8
- from django.urls import reverse
9
- {% if features.user_relations %}
10
- from django.contrib.auth.models import User
11
- {% endif %}
12
- {% if features.api_tests %}
13
- from rest_framework.test import APITestCase
14
- from rest_framework import status
15
- {% endif %}
16
- from .models import {{ app_name|pascal_case }}Model
17
-
18
-
19
- class {{ app_name|pascal_case }}ModelTest(TestCase):
20
- """Test cases for {{ app_name }} model."""
21
-
22
- def setUp(self):
23
- """Set up test data."""
24
- {% if features.user_relations %}
25
- self.user = User.objects.create_user(
26
- username='testuser',
27
- email='test@example.com',
28
- password='testpass123'
29
- )
30
- {% endif %}
31
-
32
- self.{{ app_name|snake_case }} = {{ app_name|pascal_case }}Model.objects.create(
33
- name='Test {{ app_name|title_case }}',
34
- description='Test description',
35
- {% if features.status_tracking %}status='draft',{% endif %}
36
- {% if features.user_relations %}owner=self.user{% endif %}
37
- )
38
-
39
- def test_string_representation(self):
40
- """Test string representation of model."""
41
- self.assertEqual(str(self.{{ app_name|snake_case }}), 'Test {{ app_name|title_case }}')
42
-
43
- def test_get_absolute_url(self):
44
- """Test get_absolute_url method."""
45
- url = self.{{ app_name|snake_case }}.get_absolute_url()
46
- expected_url = reverse('{{ app_name }}:detail', kwargs={'pk': self.{{ app_name|snake_case }}.pk})
47
- self.assertEqual(url, expected_url)
48
-
49
- {% if features.custom_methods %}
50
- def test_is_published(self):
51
- """Test is_published method."""
52
- {% if features.status_tracking %}
53
- self.assertFalse(self.{{ app_name|snake_case }}.is_published())
54
-
55
- self.{{ app_name|snake_case }}.status = 'published'
56
- self.{{ app_name|snake_case }}.save()
57
- self.assertTrue(self.{{ app_name|snake_case }}.is_published())
58
- {% else %}
59
- self.assertTrue(self.{{ app_name|snake_case }}.is_published())
60
- {% endif %}
61
-
62
- def test_get_display_name(self):
63
- """Test get_display_name method."""
64
- display_name = self.{{ app_name|snake_case }}.get_display_name()
65
- self.assertEqual(display_name, 'Test {{ app_name|title_case }}')
66
- {% endif %}
67
-
68
-
69
- {% if features.view_tests %}
70
- class {{ app_name|pascal_case }}ViewTest(TestCase):
71
- """Test cases for {{ app_name }} views."""
72
-
73
- def setUp(self):
74
- """Set up test data."""
75
- self.client = Client()
76
- {% if features.user_relations %}
77
- self.user = User.objects.create_user(
78
- username='testuser',
79
- email='test@example.com',
80
- password='testpass123'
81
- )
82
- {% endif %}
83
-
84
- self.{{ app_name|snake_case }} = {{ app_name|pascal_case }}Model.objects.create(
85
- name='Test {{ app_name|title_case }}',
86
- description='Test description',
87
- {% if features.status_tracking %}status='published',{% endif %}
88
- {% if features.user_relations %}owner=self.user{% endif %}
89
- )
90
-
91
- {% if features.function_based_views %}
92
- def test_index_view(self):
93
- """Test index view."""
94
- {% if features.authentication %}
95
- self.client.login(username='testuser', password='testpass123')
96
- {% endif %}
97
-
98
- url = reverse('{{ app_name }}:index')
99
- response = self.client.get(url)
100
-
101
- self.assertEqual(response.status_code, 200)
102
- self.assertContains(response, 'Test {{ app_name|title_case }}')
103
-
104
- def test_detail_view(self):
105
- """Test detail view."""
106
- {% if features.authentication %}
107
- self.client.login(username='testuser', password='testpass123')
108
- {% endif %}
109
-
110
- url = reverse('{{ app_name }}:detail', kwargs={'pk': self.{{ app_name|snake_case }}.pk})
111
- response = self.client.get(url)
112
-
113
- self.assertEqual(response.status_code, 200)
114
- self.assertContains(response, self.{{ app_name|snake_case }}.name)
115
- {% endif %}
116
-
117
- {% if features.class_based_views %}
118
- def test_list_view(self):
119
- """Test list view."""
120
- {% if features.authentication %}
121
- self.client.login(username='testuser', password='testpass123')
122
- {% endif %}
123
-
124
- url = reverse('{{ app_name }}:list')
125
- response = self.client.get(url)
126
-
127
- self.assertEqual(response.status_code, 200)
128
- self.assertContains(response, self.{{ app_name|snake_case }}.name)
129
- {% endif %}
130
-
131
- {% if features.crud_views %}
132
- def test_create_view(self):
133
- """Test create view."""
134
- {% if features.authentication %}
135
- self.client.login(username='testuser', password='testpass123')
136
- {% endif %}
137
-
138
- url = reverse('{{ app_name }}:create')
139
-
140
- # Test GET request
141
- response = self.client.get(url)
142
- self.assertEqual(response.status_code, 200)
143
-
144
- # Test POST request
145
- data = {
146
- 'name': 'New {{ app_name|title_case }}',
147
- 'description': 'New description',
148
- {% if features.status_tracking %}'status': 'draft'{% endif %}
149
- }
150
- response = self.client.post(url, data)
151
- self.assertEqual(response.status_code, 302) # Redirect after success
152
-
153
- # Verify object was created
154
- self.assertTrue(
155
- {{ app_name|pascal_case }}Model.objects.filter(name='New {{ app_name|title_case }}').exists()
156
- )
157
- {% endif %}
158
- {% endif %}
159
-
160
-
161
- {% if features.api_tests %}
162
- class {{ app_name|pascal_case }}APITest(APITestCase):
163
- """Test cases for {{ app_name }} API."""
164
-
165
- def setUp(self):
166
- """Set up test data."""
167
- {% if features.user_relations %}
168
- self.user = User.objects.create_user(
169
- username='testuser',
170
- email='test@example.com',
171
- password='testpass123'
172
- )
173
- {% endif %}
174
-
175
- self.{{ app_name|snake_case }} = {{ app_name|pascal_case }}Model.objects.create(
176
- name='Test {{ app_name|title_case }}',
177
- description='Test description',
178
- {% if features.status_tracking %}status='published',{% endif %}
179
- {% if features.user_relations %}owner=self.user{% endif %}
180
- )
181
-
182
- def test_api_view(self):
183
- """Test API view."""
184
- {% if features.authentication %}
185
- self.client.force_authenticate(user=self.user)
186
- {% endif %}
187
-
188
- url = reverse('{{ app_name }}:api')
189
- response = self.client.get(url)
190
-
191
- self.assertEqual(response.status_code, status.HTTP_200_OK)
192
- self.assertTrue(response.data['success'])
193
- self.assertEqual(len(response.data['data']), 1)
194
- self.assertEqual(response.data['data'][0]['name'], 'Test {{ app_name|title_case }}')
195
- {% endif %}
@@ -1,35 +0,0 @@
1
- """
2
- URL configuration for {{ app_name }} application.
3
-
4
- {{ description }}
5
- """
6
-
7
- from django.urls import path, include
8
- {% if features.api_views %}
9
- from django.urls import re_path
10
- {% endif %}
11
- from . import views
12
-
13
- app_name = '{{ app_name }}'
14
-
15
- urlpatterns = [
16
- {% if features.function_based_views %}
17
- path('', views.{{ app_name }}_index, name='index'),
18
- path('<int:pk>/', views.{{ app_name }}_detail, name='detail'),
19
- {% endif %}
20
-
21
- {% if features.class_based_views %}
22
- path('list/', views.{{ app_name|pascal_case }}ListView.as_view(), name='list'),
23
- path('detail/<int:pk>/', views.{{ app_name|pascal_case }}DetailView.as_view(), name='detail'),
24
-
25
- {% if features.crud_views %}
26
- path('create/', views.{{ app_name|pascal_case }}CreateView.as_view(), name='create'),
27
- path('update/<int:pk>/', views.{{ app_name|pascal_case }}UpdateView.as_view(), name='update'),
28
- path('delete/<int:pk>/', views.{{ app_name|pascal_case }}DeleteView.as_view(), name='delete'),
29
- {% endif %}
30
- {% endif %}
31
-
32
- {% if features.api_views %}
33
- path('api/', views.{{ app_name|pascal_case }}APIView.as_view(), name='api'),
34
- {% endif %}
35
- ]