django-cfg 1.3.9__py3-none-any.whl → 1.3.11__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 (187) hide show
  1. django_cfg/__init__.py +1 -1
  2. django_cfg/apps/payments/admin/networks_admin.py +12 -1
  3. django_cfg/apps/payments/admin/payments_admin.py +13 -0
  4. django_cfg/apps/payments/admin_interface/serializers/payment_serializers.py +62 -14
  5. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_card.html +121 -0
  6. django_cfg/apps/payments/admin_interface/templates/payments/components/payment_qr_code.html +95 -0
  7. django_cfg/apps/payments/admin_interface/templates/payments/components/progress_bar.html +37 -0
  8. django_cfg/apps/payments/admin_interface/templates/payments/components/provider_stats.html +60 -0
  9. django_cfg/apps/payments/admin_interface/templates/payments/components/status_badge.html +41 -0
  10. django_cfg/apps/payments/admin_interface/templates/payments/components/status_overview.html +83 -0
  11. django_cfg/apps/payments/admin_interface/templates/payments/payment_detail.html +363 -0
  12. django_cfg/apps/payments/admin_interface/templates/payments/payment_form.html +33 -3
  13. django_cfg/apps/payments/admin_interface/views/api/payments.py +102 -0
  14. django_cfg/apps/payments/admin_interface/views/api/webhook_admin.py +96 -45
  15. django_cfg/apps/payments/admin_interface/views/forms.py +5 -1
  16. django_cfg/apps/payments/config/__init__.py +14 -15
  17. django_cfg/apps/payments/config/django_cfg_integration.py +59 -1
  18. django_cfg/apps/payments/config/helpers.py +8 -13
  19. django_cfg/apps/payments/migrations/0001_initial.py +33 -46
  20. django_cfg/apps/payments/migrations/0002_rename_payments_un_user_id_7f6e79_idx_payments_un_user_id_8ce187_idx_and_more.py +46 -0
  21. django_cfg/apps/payments/migrations/0003_universalpayment_status_changed_at.py +25 -0
  22. django_cfg/apps/payments/models/managers/payment_managers.py +142 -25
  23. django_cfg/apps/payments/models/payments.py +94 -0
  24. django_cfg/apps/payments/services/core/base.py +4 -4
  25. django_cfg/apps/payments/services/core/payment_service.py +265 -38
  26. django_cfg/apps/payments/services/providers/base.py +209 -3
  27. django_cfg/apps/payments/services/providers/models/__init__.py +2 -0
  28. django_cfg/apps/payments/services/providers/models/base.py +25 -2
  29. django_cfg/apps/payments/services/providers/nowpayments/models.py +2 -2
  30. django_cfg/apps/payments/services/providers/nowpayments/provider.py +57 -9
  31. django_cfg/apps/payments/services/providers/registry.py +5 -5
  32. django_cfg/apps/payments/services/types/requests.py +19 -7
  33. django_cfg/apps/payments/signals/payment_signals.py +31 -2
  34. django_cfg/apps/payments/static/payments/js/api-client.js +6 -1
  35. django_cfg/apps/payments/static/payments/js/payment-detail.js +167 -0
  36. django_cfg/apps/payments/static/payments/js/payment-form.js +35 -26
  37. django_cfg/apps/payments/templatetags/payment_tags.py +8 -0
  38. django_cfg/apps/payments/urls.py +3 -2
  39. django_cfg/apps/payments/views/api/currencies.py +3 -0
  40. django_cfg/apps/payments/views/serializers/currencies.py +18 -5
  41. django_cfg/apps/tasks/admin/tasks_admin.py +2 -2
  42. django_cfg/apps/tasks/static/tasks/css/dashboard.css +68 -217
  43. django_cfg/apps/tasks/static/tasks/js/api.js +40 -84
  44. django_cfg/apps/tasks/static/tasks/js/components/DataManager.js +24 -0
  45. django_cfg/apps/tasks/static/tasks/js/components/TabManager.js +85 -0
  46. django_cfg/apps/tasks/static/tasks/js/components/TaskRenderer.js +216 -0
  47. django_cfg/apps/tasks/static/tasks/js/dashboard/main.mjs +245 -0
  48. django_cfg/apps/tasks/static/tasks/js/dashboard/overview.mjs +123 -0
  49. django_cfg/apps/tasks/static/tasks/js/dashboard/queues.mjs +120 -0
  50. django_cfg/apps/tasks/static/tasks/js/dashboard/tasks.mjs +350 -0
  51. django_cfg/apps/tasks/static/tasks/js/dashboard/workers.mjs +169 -0
  52. django_cfg/apps/tasks/tasks/__init__.py +10 -0
  53. django_cfg/apps/tasks/tasks/demo_tasks.py +133 -0
  54. django_cfg/apps/tasks/templates/tasks/components/management_actions.html +42 -45
  55. django_cfg/apps/tasks/templates/tasks/components/{status_cards.html → overview_content.html} +30 -11
  56. django_cfg/apps/tasks/templates/tasks/components/queues_content.html +19 -0
  57. django_cfg/apps/tasks/templates/tasks/components/tab_navigation.html +16 -10
  58. django_cfg/apps/tasks/templates/tasks/components/tasks_content.html +51 -0
  59. django_cfg/apps/tasks/templates/tasks/components/workers_content.html +30 -0
  60. django_cfg/apps/tasks/templates/tasks/layout/base.html +117 -0
  61. django_cfg/apps/tasks/templates/tasks/pages/dashboard.html +82 -0
  62. django_cfg/apps/tasks/templates/tasks/partials/task_row_template.html +40 -0
  63. django_cfg/apps/tasks/templates/tasks/widgets/task_filters.html +37 -0
  64. django_cfg/apps/tasks/templates/tasks/widgets/task_footer.html +41 -0
  65. django_cfg/apps/tasks/templates/tasks/widgets/task_table.html +50 -0
  66. django_cfg/apps/tasks/urls.py +2 -2
  67. django_cfg/apps/tasks/urls_admin.py +2 -2
  68. django_cfg/apps/tasks/utils/__init__.py +1 -0
  69. django_cfg/apps/tasks/utils/simulator.py +356 -0
  70. django_cfg/apps/tasks/views/__init__.py +16 -0
  71. django_cfg/apps/tasks/views/api.py +569 -0
  72. django_cfg/apps/tasks/views/dashboard.py +58 -0
  73. django_cfg/core/integration/__init__.py +21 -0
  74. django_cfg/management/commands/rundramatiq_simulator.py +430 -0
  75. django_cfg/models/constance.py +0 -11
  76. django_cfg/models/payments.py +137 -3
  77. django_cfg/modules/django_tasks.py +54 -21
  78. django_cfg/registry/core.py +4 -9
  79. django_cfg/template_archive/django_sample.zip +0 -0
  80. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/METADATA +2 -2
  81. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/RECORD +84 -152
  82. django_cfg/apps/payments/config/constance/__init__.py +0 -22
  83. django_cfg/apps/payments/config/constance/config_service.py +0 -123
  84. django_cfg/apps/payments/config/constance/fields.py +0 -69
  85. django_cfg/apps/payments/config/constance/settings.py +0 -160
  86. django_cfg/apps/payments/migrations/0002_currency_usd_rate_currency_usd_rate_updated_at.py +0 -26
  87. django_cfg/apps/payments/migrations/0003_remove_provider_currency_fields.py +0 -28
  88. django_cfg/apps/payments/migrations/0004_add_reserved_usd_field.py +0 -30
  89. django_cfg/apps/tasks/static/tasks/js/dashboard.js +0 -614
  90. django_cfg/apps/tasks/static/tasks/js/modals.js +0 -452
  91. django_cfg/apps/tasks/static/tasks/js/notifications.js +0 -144
  92. django_cfg/apps/tasks/static/tasks/js/task-monitor.js +0 -454
  93. django_cfg/apps/tasks/static/tasks/js/theme.js +0 -77
  94. django_cfg/apps/tasks/templates/tasks/base.html +0 -96
  95. django_cfg/apps/tasks/templates/tasks/components/info_cards.html +0 -85
  96. django_cfg/apps/tasks/templates/tasks/components/overview_tab.html +0 -22
  97. django_cfg/apps/tasks/templates/tasks/components/queues_tab.html +0 -19
  98. django_cfg/apps/tasks/templates/tasks/components/task_details_modal.html +0 -103
  99. django_cfg/apps/tasks/templates/tasks/components/tasks_tab.html +0 -32
  100. django_cfg/apps/tasks/templates/tasks/components/workers_tab.html +0 -29
  101. django_cfg/apps/tasks/templates/tasks/dashboard.html +0 -29
  102. django_cfg/apps/tasks/views.py +0 -461
  103. django_cfg/management/commands/app_agent_diagnose.py +0 -470
  104. django_cfg/management/commands/app_agent_generate.py +0 -342
  105. django_cfg/management/commands/app_agent_info.py +0 -308
  106. django_cfg/management/commands/auto_generate.py +0 -486
  107. django_cfg/modules/django_app_agent/__init__.py +0 -87
  108. django_cfg/modules/django_app_agent/agents/__init__.py +0 -40
  109. django_cfg/modules/django_app_agent/agents/base/__init__.py +0 -24
  110. django_cfg/modules/django_app_agent/agents/base/agent.py +0 -354
  111. django_cfg/modules/django_app_agent/agents/base/context.py +0 -236
  112. django_cfg/modules/django_app_agent/agents/base/executor.py +0 -430
  113. django_cfg/modules/django_app_agent/agents/generation/__init__.py +0 -12
  114. django_cfg/modules/django_app_agent/agents/generation/app_generator/__init__.py +0 -15
  115. django_cfg/modules/django_app_agent/agents/generation/app_generator/config_validator.py +0 -147
  116. django_cfg/modules/django_app_agent/agents/generation/app_generator/main.py +0 -99
  117. django_cfg/modules/django_app_agent/agents/generation/app_generator/models.py +0 -32
  118. django_cfg/modules/django_app_agent/agents/generation/app_generator/prompt_manager.py +0 -290
  119. django_cfg/modules/django_app_agent/agents/interfaces.py +0 -376
  120. django_cfg/modules/django_app_agent/core/__init__.py +0 -33
  121. django_cfg/modules/django_app_agent/core/config.py +0 -300
  122. django_cfg/modules/django_app_agent/core/exceptions.py +0 -359
  123. django_cfg/modules/django_app_agent/models/__init__.py +0 -71
  124. django_cfg/modules/django_app_agent/models/base.py +0 -283
  125. django_cfg/modules/django_app_agent/models/context.py +0 -496
  126. django_cfg/modules/django_app_agent/models/enums.py +0 -481
  127. django_cfg/modules/django_app_agent/models/requests.py +0 -500
  128. django_cfg/modules/django_app_agent/models/responses.py +0 -585
  129. django_cfg/modules/django_app_agent/pytest.ini +0 -6
  130. django_cfg/modules/django_app_agent/services/__init__.py +0 -42
  131. django_cfg/modules/django_app_agent/services/app_generator/__init__.py +0 -30
  132. django_cfg/modules/django_app_agent/services/app_generator/ai_integration.py +0 -133
  133. django_cfg/modules/django_app_agent/services/app_generator/context.py +0 -40
  134. django_cfg/modules/django_app_agent/services/app_generator/main.py +0 -202
  135. django_cfg/modules/django_app_agent/services/app_generator/structure.py +0 -316
  136. django_cfg/modules/django_app_agent/services/app_generator/validation.py +0 -125
  137. django_cfg/modules/django_app_agent/services/base.py +0 -437
  138. django_cfg/modules/django_app_agent/services/context_builder/__init__.py +0 -34
  139. django_cfg/modules/django_app_agent/services/context_builder/code_extractor.py +0 -141
  140. django_cfg/modules/django_app_agent/services/context_builder/context_generator.py +0 -276
  141. django_cfg/modules/django_app_agent/services/context_builder/main.py +0 -272
  142. django_cfg/modules/django_app_agent/services/context_builder/models.py +0 -40
  143. django_cfg/modules/django_app_agent/services/context_builder/pattern_analyzer.py +0 -85
  144. django_cfg/modules/django_app_agent/services/project_scanner/__init__.py +0 -31
  145. django_cfg/modules/django_app_agent/services/project_scanner/app_discovery.py +0 -311
  146. django_cfg/modules/django_app_agent/services/project_scanner/main.py +0 -221
  147. django_cfg/modules/django_app_agent/services/project_scanner/models.py +0 -59
  148. django_cfg/modules/django_app_agent/services/project_scanner/pattern_detection.py +0 -94
  149. django_cfg/modules/django_app_agent/services/questioning_service/__init__.py +0 -28
  150. django_cfg/modules/django_app_agent/services/questioning_service/main.py +0 -273
  151. django_cfg/modules/django_app_agent/services/questioning_service/models.py +0 -111
  152. django_cfg/modules/django_app_agent/services/questioning_service/question_generator.py +0 -251
  153. django_cfg/modules/django_app_agent/services/questioning_service/response_processor.py +0 -347
  154. django_cfg/modules/django_app_agent/services/questioning_service/session_manager.py +0 -356
  155. django_cfg/modules/django_app_agent/services/report_service.py +0 -332
  156. django_cfg/modules/django_app_agent/services/template_manager/__init__.py +0 -18
  157. django_cfg/modules/django_app_agent/services/template_manager/jinja_engine.py +0 -236
  158. django_cfg/modules/django_app_agent/services/template_manager/main.py +0 -159
  159. django_cfg/modules/django_app_agent/services/template_manager/models.py +0 -36
  160. django_cfg/modules/django_app_agent/services/template_manager/template_loader.py +0 -100
  161. django_cfg/modules/django_app_agent/services/template_manager/templates/admin.py.j2 +0 -105
  162. django_cfg/modules/django_app_agent/services/template_manager/templates/apps.py.j2 +0 -31
  163. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_config.py.j2 +0 -44
  164. django_cfg/modules/django_app_agent/services/template_manager/templates/cfg_module.py.j2 +0 -81
  165. django_cfg/modules/django_app_agent/services/template_manager/templates/forms.py.j2 +0 -107
  166. django_cfg/modules/django_app_agent/services/template_manager/templates/models.py.j2 +0 -139
  167. django_cfg/modules/django_app_agent/services/template_manager/templates/serializers.py.j2 +0 -91
  168. django_cfg/modules/django_app_agent/services/template_manager/templates/tests.py.j2 +0 -195
  169. django_cfg/modules/django_app_agent/services/template_manager/templates/urls.py.j2 +0 -35
  170. django_cfg/modules/django_app_agent/services/template_manager/templates/views.py.j2 +0 -211
  171. django_cfg/modules/django_app_agent/services/template_manager/variable_processor.py +0 -200
  172. django_cfg/modules/django_app_agent/services/validation_service/__init__.py +0 -25
  173. django_cfg/modules/django_app_agent/services/validation_service/django_validator.py +0 -333
  174. django_cfg/modules/django_app_agent/services/validation_service/main.py +0 -242
  175. django_cfg/modules/django_app_agent/services/validation_service/models.py +0 -66
  176. django_cfg/modules/django_app_agent/services/validation_service/quality_validator.py +0 -352
  177. django_cfg/modules/django_app_agent/services/validation_service/security_validator.py +0 -272
  178. django_cfg/modules/django_app_agent/services/validation_service/syntax_validator.py +0 -203
  179. django_cfg/modules/django_app_agent/ui/__init__.py +0 -25
  180. django_cfg/modules/django_app_agent/ui/cli.py +0 -419
  181. django_cfg/modules/django_app_agent/ui/rich_components.py +0 -622
  182. django_cfg/modules/django_app_agent/utils/__init__.py +0 -38
  183. django_cfg/modules/django_app_agent/utils/logging.py +0 -360
  184. django_cfg/modules/django_app_agent/utils/validation.py +0 -417
  185. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/WHEEL +0 -0
  186. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.dist-info}/entry_points.txt +0 -0
  187. {django_cfg-1.3.9.dist-info → django_cfg-1.3.11.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
- ]