From e24fb36dead22ff0aea76d88571314e337069aad Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Sat, 31 Jan 2026 22:23:57 +0545 Subject: [PATCH] chore(djinit/templates): purge obsolete template components Remove legacy template placeholders that are no longer used in the project scaffold. - New Features: - Enhancements: Removed unused template files - Bug Fixes: --- djinit/templates/components/admin.py-tpl | 5 - djinit/templates/components/api_readme.md-tpl | 76 ------ djinit/templates/components/apps.py-tpl | 12 - djinit/templates/components/models.py-tpl | 3 - .../templates/components/models_readme.md-tpl | 119 ---------- djinit/templates/components/routes.py-tpl | 8 - .../templates/components/serializers.py-tpl | 3 - djinit/templates/components/tests.py-tpl | 3 - djinit/templates/components/views.py-tpl | 3 - djinit/templates/config/asgi.py-tpl | 11 - djinit/templates/config/settings/base.py-tpl | 179 -------------- .../config/settings/development.py-tpl | 42 ---- .../config/settings/production.py-tpl | 65 ------ djinit/templates/config/urls.py-tpl | 103 -------- djinit/templates/config/wsgi.py-tpl | 12 - .../predefined/apps/generic/models.py-tpl | 18 -- .../apps/generic/serializers.py-tpl | 11 - .../predefined/apps/generic/services.py-tpl | 36 --- .../predefined/apps/generic/tests.py-tpl | 55 ----- .../predefined/apps/generic/views.py-tpl | 62 ----- .../predefined/apps/users/models.py-tpl | 9 - .../predefined/apps/users/serializers.py-tpl | 9 - .../predefined/apps/users/services.py-tpl | 10 - .../predefined/apps/users/tests.py-tpl | 12 - .../predefined/apps/users/views.py-tpl | 13 -- .../presets/predefined/core/exceptions.py-tpl | 5 - .../core/middleware/request_logger.py-tpl | 14 -- .../core/mixins/timestamped_model.py-tpl | 9 - .../predefined/core/utils/responses.py-tpl | 17 -- .../presets/unified/apps/core/apps.py-tpl | 8 - .../unified/apps/core/models/__init__.py-tpl | 4 - .../unified/apps/core/models/base.py-tpl | 13 -- .../unified/apps/core/models/mixins.py-tpl | 13 -- .../unified/apps/core/utils/__init__.py-tpl | 3 - .../templates/project/ci/github_actions-tpl | 109 --------- djinit/templates/project/ci/gitlab_ci-tpl | 133 ----------- djinit/templates/project/env_sample-tpl | 32 --- djinit/templates/project/gitignore-tpl | 93 -------- djinit/templates/project/init.py-tpl | 0 djinit/templates/project/justfile-tpl | 219 ------------------ djinit/templates/project/manage.py-tpl | 32 --- djinit/templates/project/procfile-tpl | 20 -- djinit/templates/project/pyproject.toml-tpl | 46 ---- djinit/templates/project/readme.md-tpl | 201 ---------------- djinit/templates/project/requirements-tpl | 19 -- djinit/templates/project/runtime_txt-tpl | 1 - 46 files changed, 1870 deletions(-) delete mode 100644 djinit/templates/components/admin.py-tpl delete mode 100644 djinit/templates/components/api_readme.md-tpl delete mode 100644 djinit/templates/components/apps.py-tpl delete mode 100644 djinit/templates/components/models.py-tpl delete mode 100644 djinit/templates/components/models_readme.md-tpl delete mode 100644 djinit/templates/components/routes.py-tpl delete mode 100644 djinit/templates/components/serializers.py-tpl delete mode 100644 djinit/templates/components/tests.py-tpl delete mode 100644 djinit/templates/components/views.py-tpl delete mode 100644 djinit/templates/config/asgi.py-tpl delete mode 100644 djinit/templates/config/settings/base.py-tpl delete mode 100644 djinit/templates/config/settings/development.py-tpl delete mode 100644 djinit/templates/config/settings/production.py-tpl delete mode 100644 djinit/templates/config/urls.py-tpl delete mode 100644 djinit/templates/config/wsgi.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/generic/models.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/generic/serializers.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/generic/services.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/generic/tests.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/generic/views.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/users/models.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/users/serializers.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/users/services.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/users/tests.py-tpl delete mode 100644 djinit/templates/presets/predefined/apps/users/views.py-tpl delete mode 100644 djinit/templates/presets/predefined/core/exceptions.py-tpl delete mode 100644 djinit/templates/presets/predefined/core/middleware/request_logger.py-tpl delete mode 100644 djinit/templates/presets/predefined/core/mixins/timestamped_model.py-tpl delete mode 100644 djinit/templates/presets/predefined/core/utils/responses.py-tpl delete mode 100644 djinit/templates/presets/unified/apps/core/apps.py-tpl delete mode 100644 djinit/templates/presets/unified/apps/core/models/__init__.py-tpl delete mode 100644 djinit/templates/presets/unified/apps/core/models/base.py-tpl delete mode 100644 djinit/templates/presets/unified/apps/core/models/mixins.py-tpl delete mode 100644 djinit/templates/presets/unified/apps/core/utils/__init__.py-tpl delete mode 100644 djinit/templates/project/ci/github_actions-tpl delete mode 100644 djinit/templates/project/ci/gitlab_ci-tpl delete mode 100644 djinit/templates/project/env_sample-tpl delete mode 100644 djinit/templates/project/gitignore-tpl delete mode 100644 djinit/templates/project/init.py-tpl delete mode 100644 djinit/templates/project/justfile-tpl delete mode 100644 djinit/templates/project/manage.py-tpl delete mode 100644 djinit/templates/project/procfile-tpl delete mode 100644 djinit/templates/project/pyproject.toml-tpl delete mode 100644 djinit/templates/project/readme.md-tpl delete mode 100644 djinit/templates/project/requirements-tpl delete mode 100644 djinit/templates/project/runtime_txt-tpl diff --git a/djinit/templates/components/admin.py-tpl b/djinit/templates/components/admin.py-tpl deleted file mode 100644 index dc9bfc6..0000000 --- a/djinit/templates/components/admin.py-tpl +++ /dev/null @@ -1,5 +0,0 @@ -"""generated with djinit""" - -from django.contrib import admin - -# Register your models here. diff --git a/djinit/templates/components/api_readme.md-tpl b/djinit/templates/components/api_readme.md-tpl deleted file mode 100644 index 5d416ff..0000000 --- a/djinit/templates/components/api_readme.md-tpl +++ /dev/null @@ -1,76 +0,0 @@ -# API Directory - -This directory contains your API endpoints organized by model/resource. - -## Structure - -For each model in your `models/` directory, create a corresponding subdirectory here with the following files: - -``` -api/ -├── __init__.py -├── urls.py # Main API URL router -└── / # e.g., user, product, order - ├── __init__.py - ├── views.py - ├── serializers.py - └── urls.py -``` - -## Example - -If you have a `User` model in `models/user.py`, create: - -### 1. `api/user/serializers.py` -```python -from rest_framework import serializers -from [[ module_name ]].models.user import User - -class UserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = '__all__' -``` - -### 2. `api/user/views.py` -```python -from rest_framework import viewsets -from [[ module_name ]].models.user import User -from .serializers import UserSerializer - -class UserViewSet(viewsets.ModelViewSet): - queryset = User.objects.all() - serializer_class = UserSerializer -``` - -### 3. `api/user/urls.py` -```python -from django.urls import path, include -from rest_framework.routers import DefaultRouter -from .views import UserViewSet - -router = DefaultRouter() -router.register(r'', UserViewSet, basename='user') - -urlpatterns = [ - path('', include(router.urls)), -] -``` - -### 4. Update `api/urls.py` -```python -from django.urls import path, include - -urlpatterns = [ - path('user/', include('[[ module_name ]].api.user.urls')), - # Add more API endpoints here -] -``` - -## Best Practices - -1. **One model per subdirectory**: Keep API endpoints for each model in its own subdirectory -2. **Consistent naming**: Use lowercase, plural names for API endpoints (e.g., `users/`, `products/`) -3. **Version your API**: Consider adding versioning (e.g., `api/v1/user/`) -4. **Use ViewSets**: Leverage DRF's ViewSets for standard CRUD operations -5. **Custom actions**: Add custom actions using `@action` decorator for non-CRUD operations diff --git a/djinit/templates/components/apps.py-tpl b/djinit/templates/components/apps.py-tpl deleted file mode 100644 index fdac009..0000000 --- a/djinit/templates/components/apps.py-tpl +++ /dev/null @@ -1,12 +0,0 @@ -from django.apps import AppConfig - - - -class [[ app_config_name ]]Config(AppConfig): - default_auto_field = 'django.db.models.BigAutoField' -# @IF app_module - name = '[[ app_module ]]' -# @ENDIF -# @IF not app_module - name = '[[ app_name ]]' -# @ENDIF diff --git a/djinit/templates/components/models.py-tpl b/djinit/templates/components/models.py-tpl deleted file mode 100644 index 71a8362..0000000 --- a/djinit/templates/components/models.py-tpl +++ /dev/null @@ -1,3 +0,0 @@ -from django.db import models - -# Create your models here. diff --git a/djinit/templates/components/models_readme.md-tpl b/djinit/templates/components/models_readme.md-tpl deleted file mode 100644 index 0bf247c..0000000 --- a/djinit/templates/components/models_readme.md-tpl +++ /dev/null @@ -1,119 +0,0 @@ -# Models Directory - -This directory contains your Django models. - -## Structure - -Organize your models as individual Python files: - -``` -models/ -├── __init__.py -├── user.py -├── product.py -└── order.py -``` - -## Creating a Model - -### 1. Create the model file (e.g., `models/user.py`) - -```python -from django.db import models -from django.contrib.auth.models import AbstractUser - -class User(AbstractUser): - """Custom user model.""" - bio = models.TextField(blank=True) - avatar = models.ImageField(upload_to='avatars/', blank=True, null=True) - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - db_table = 'users' - verbose_name = 'User' - verbose_name_plural = 'Users' - - def __str__(self): - return self.username -``` - -### 2. Import in `models/__init__.py` - -```python -from .user import User -from .product import Product -from .order import Order - -__all__ = ['User', 'Product', 'Order'] -``` - -### 3. Create corresponding API endpoints - -After creating a model, create the corresponding API structure in the `api/` directory: - -``` -api/ -└── user/ - ├── __init__.py - ├── views.py - ├── serializers.py - └── urls.py -``` - -See the `api/README.md` for detailed instructions on creating API endpoints. - -### 4. Register in admin (optional) - -Create or update `admin/__init__.py`: - -```python -from django.contrib import admin -from [[ module_name ]].models import User - -@admin.register(User) -class UserAdmin(admin.ModelAdmin): - list_display = ['username', 'email', 'created_at'] - search_fields = ['username', 'email'] - list_filter = ['is_active', 'created_at'] -``` - -## Best Practices - -1. **One model per file**: Keep each model in its own file for better organization -2. **Use meaningful names**: Choose clear, descriptive names for models and fields -3. **Add Meta class**: Define `db_table`, `verbose_name`, and other metadata -4. **Implement __str__**: Always define a meaningful `__str__` method -5. **Use mixins**: Create reusable mixins for common fields (e.g., timestamps) -6. **Add docstrings**: Document your models with clear docstrings - -## Common Model Patterns - -### Timestamped Model Mixin - -```python -class TimestampedModel(models.Model): - """Abstract base class with timestamp fields.""" - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - abstract = True -``` - -### Soft Delete Mixin - -```python -class SoftDeleteModel(models.Model): - """Abstract base class with soft delete functionality.""" - is_deleted = models.BooleanField(default=False) - deleted_at = models.DateTimeField(null=True, blank=True) - - class Meta: - abstract = True - - def delete(self, *args, **kwargs): - self.is_deleted = True - self.deleted_at = timezone.now() - self.save() -``` diff --git a/djinit/templates/components/routes.py-tpl b/djinit/templates/components/routes.py-tpl deleted file mode 100644 index 37b00a9..0000000 --- a/djinit/templates/components/routes.py-tpl +++ /dev/null @@ -1,8 +0,0 @@ -from rest_framework.routers import DefaultRouter - -router = DefaultRouter() - -# Register your viewsets here -# router.register(r'endpoint', YourViewSet, basename='your-endpoint') - -urlpatterns = router.urls diff --git a/djinit/templates/components/serializers.py-tpl b/djinit/templates/components/serializers.py-tpl deleted file mode 100644 index 2774c36..0000000 --- a/djinit/templates/components/serializers.py-tpl +++ /dev/null @@ -1,3 +0,0 @@ -from rest_framework import serializers - -# Create your serializers here. diff --git a/djinit/templates/components/tests.py-tpl b/djinit/templates/components/tests.py-tpl deleted file mode 100644 index 7ce503c..0000000 --- a/djinit/templates/components/tests.py-tpl +++ /dev/null @@ -1,3 +0,0 @@ -from django.test import TestCase - -# Create your tests here. diff --git a/djinit/templates/components/views.py-tpl b/djinit/templates/components/views.py-tpl deleted file mode 100644 index 91ea44a..0000000 --- a/djinit/templates/components/views.py-tpl +++ /dev/null @@ -1,3 +0,0 @@ -from django.shortcuts import render - -# Create your views here. diff --git a/djinit/templates/config/asgi.py-tpl b/djinit/templates/config/asgi.py-tpl deleted file mode 100644 index 0c5c879..0000000 --- a/djinit/templates/config/asgi.py-tpl +++ /dev/null @@ -1,11 +0,0 @@ -"""generated with djinit""" - -import os -import environ -from django.core.asgi import get_asgi_application - -env = environ.Env() -environ.Env.read_env() - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", env("DJANGO_SETTINGS_MODULE", default="[[ project_name ]].settings.production")) -application = get_asgi_application() diff --git a/djinit/templates/config/settings/base.py-tpl b/djinit/templates/config/settings/base.py-tpl deleted file mode 100644 index f33b399..0000000 --- a/djinit/templates/config/settings/base.py-tpl +++ /dev/null @@ -1,179 +0,0 @@ -""" -generated with djinit -Common settings shared between development and production environment -""" - -import os -from datetime import timedelta -from pathlib import Path - -import environ - -env = environ.Env() -environ.Env.read_env() - -# Build paths inside the project like this: BASE_DIR / 'subdir'. -BASE_DIR = Path(__file__).resolve().parent.parent.parent - -# Quick-start development settings - unsuitable for production -# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/ - - -# Application definition -THIRD_PARTY_APPS = [ - "rest_framework", - "rest_framework_simplejwt", - "rest_framework_simplejwt.token_blacklist", - "corsheaders", - "drf_spectacular", -] - -USER_DEFINED_APPS = [ -# @LOOP app in app_names "[[ app ]]", -# @ENDLOOP -] - -BUILT_IN_APPS = [ - "django.contrib.admin", - "django.contrib.auth", - "django.contrib.contenttypes", - "django.contrib.sessions", - "django.contrib.messages", - "django.contrib.staticfiles", -] - -INSTALLED_APPS = BUILT_IN_APPS + THIRD_PARTY_APPS + USER_DEFINED_APPS -INSTALLED_APPS.insert(0, "jazzmin") - -MIDDLEWARE = [ - "corsheaders.middleware.CorsMiddleware", - "django.middleware.security.SecurityMiddleware", - "whitenoise.middleware.WhiteNoiseMiddleware", - "django.contrib.sessions.middleware.SessionMiddleware", - "django.middleware.common.CommonMiddleware", - "django.middleware.csrf.CsrfViewMiddleware", - "django.contrib.auth.middleware.AuthenticationMiddleware", - "django.contrib.messages.middleware.MessageMiddleware", - "django.middleware.clickjacking.XFrameOptionsMiddleware", -] - -ROOT_URLCONF = "[[ project_name ]].urls" - -TEMPLATES = [ - { - "BACKEND": "django.template.backends.django.DjangoTemplates", - "DIRS": [], - "APP_DIRS": True, - "OPTIONS": { - "context_processors": [ - "django.template.context_processors.request", - "django.contrib.auth.context_processors.auth", - "django.contrib.messages.context_processors.messages", - ], - }, - }, -] - -WSGI_APPLICATION = "[[ project_name ]].wsgi.application" - - -# Password validation -# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators - -AUTH_PASSWORD_VALIDATORS = [ - { - "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", - }, - { - "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", - }, -] - - -# Internationalization -# https://docs.djangoproject.com/en/5.2/topics/i18n/ - -LANGUAGE_CODE = "en-us" -TIME_ZONE = "UTC" -USE_I18N = True -USE_TZ = True - -# Static files and media files -STATIC_URL = "static/" -STATIC_ROOT = BASE_DIR / "staticfiles" - -MEDIA_URL = "media/" -MEDIA_ROOT = BASE_DIR / "media" - -STATICFILES_STORAGE = "whitenoise.storage.CompressedManifestStaticFilesStorage" - -DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField" - -# REST Framework Settings -REST_FRAMEWORK = { - "DEFAULT_RENDERER_CLASSES": [ - "rest_framework.renderers.JSONRenderer", - ], - "DEFAULT_PARSER_CLASSES": [ - "rest_framework.parsers.JSONParser", - ], - "DEFAULT_AUTHENTICATION_CLASSES": ( - "rest_framework_simplejwt.authentication.JWTAuthentication", - "rest_framework.authentication.SessionAuthentication", - ), - "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", - "DEFAULT_PAGINATION_CLASS": "rest_framework.pagination.PageNumberPagination", - "PAGE_SIZE": 20, -} - -# DRF Spectacular settings -SPECTACULAR_SETTINGS = { - "TITLE": "[[ project_name ]] API", - "DESCRIPTION": "API documentation for [[ project_name ]]", - "VERSION": "1.0.0", - "SERVE_INCLUDE_SCHEMA": False, - "COMPONENT_SPLIT_REQUEST": True, - "SCHEMA_PATH_PREFIX": "/api/", -} - -# JWT Settings -SIMPLE_JWT = { - "ACCESS_TOKEN_LIFETIME": timedelta(days=1), - "REFRESH_TOKEN_LIFETIME": timedelta(days=3), - "ROTATE_REFRESH_TOKENS": True, - "BLACKLIST_AFTER_ROTATION": True, -} - -# CORS Settings -CORS_ALLOW_METHODS = [ - "DELETE", - "GET", - "OPTIONS", - "PATCH", - "POST", - "PUT", -] - -CORS_ALLOW_HEADERS = [ - "accept", - "accept-encoding", - "authorization", - "content-type", - "dnt", - "origin", - "user-agent", - "x-csrftoken", - "x-requested-with", -] - -CORS_PREFLIGHT_MAX_AGE = 86400 # 24 hours -# Security Settings -SECURE_BROWSER_XSS_FILTER = True -SECURE_CONTENT_TYPE_NOSNIFF = True -X_FRAME_OPTIONS = "DENY" diff --git a/djinit/templates/config/settings/development.py-tpl b/djinit/templates/config/settings/development.py-tpl deleted file mode 100644 index 2e3c1b3..0000000 --- a/djinit/templates/config/settings/development.py-tpl +++ /dev/null @@ -1,42 +0,0 @@ -"""generated with djinit""" - -from .base import * - -SECRET_KEY = "[[ secret_key ]]" - -# SECURITY WARNING: don't run with debug turned on in production! -DEBUG = True - -ALLOWED_HOSTS = ["*"] - -# Database -# https://docs.djangoproject.com/en/5.2/ref/settings/#databases - -DATABASES = { - "default": { - "ENGINE": "django.db.backends.sqlite3", - "NAME": BASE_DIR / "db.sqlite3", - "OPTIONS": { - "transaction_mode": "IMMEDIATE", - "timeout": 5, # seconds - "init_command": """ - PRAGMA journal_mode=WAL; - PRAGMA synchronous=NORMAL; - PRAGMA mmap_size = 134217728; - PRAGMA journal_size_limit = 27103364; - PRAGMA cache_size=2000; - """, - }, - } -} - -# Email backend for development -EMAIL_BACKEND = "django.core.mail.backends.console.EmailBackend" - -# CORS settings for development -# Allow all origins in development (convenient but not secure) -CORS_ALLOW_ALL_ORIGINS = True -CORS_ALLOW_CREDENTIALS = True - -# Disable HTTPS redirect in development -SECURE_SSL_REDIRECT = False diff --git a/djinit/templates/config/settings/production.py-tpl b/djinit/templates/config/settings/production.py-tpl deleted file mode 100644 index 7d58363..0000000 --- a/djinit/templates/config/settings/production.py-tpl +++ /dev/null @@ -1,65 +0,0 @@ -"""generated with djinit""" - -from .base import * -import dj_database_url - -DEBUG = False -SECRET_KEY = env('SECRET_KEY') -ALLOWED_HOSTS = env.list('ALLOWED_HOSTS', default=[]) - -# Database -# @IF use_database_url -# Using dj_database_url (recommended for production) -DATABASES = { - 'default': env.db('DATABASE_URL') -} -# @ELSE -# Using individual database parameters -DATABASES = { - 'default': { - # @IF database_type == 'mysql' - 'ENGINE': 'django.db.backends.mysql', - 'PORT': env('DB_PORT', default='3306'), - # @ELSE - 'ENGINE': 'django.db.backends.postgresql', - 'PORT': env('DB_PORT', default='5432'), - # @ENDIF - 'NAME': env('DB_NAME'), - 'USER': env('DB_USER'), - 'PASSWORD': env('DB_PASSWORD'), - 'HOST': env('DB_HOST'), - } -} -# @ENDIF - -# CORS settings for production -# Filter out empty strings from FRONTEND_URL -CORS_ALLOWED_ORIGINS = env.list('FRONTEND_URL', default=[]) -CORS_ALLOW_CREDENTIALS = True - -# Additional CORS security for production -CORS_ALLOW_PRIVATE_NETWORK = False - -# Email settings -EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend' -EMAIL_HOST = env('EMAIL_HOST') -EMAIL_PORT = env.int('EMAIL_PORT', default=587) -EMAIL_USE_TLS = env.bool('EMAIL_USE_TLS', default=True) -EMAIL_HOST_USER = env('EMAIL_HOST_USER') -EMAIL_HOST_PASSWORD = env('EMAIL_HOST_PASSWORD') -DEFAULT_FROM_EMAIL = env('EMAIL_HOST_USER') -SERVER_EMAIL = env('EMAIL_HOST_USER') - -# Security settings for production -SECURE_SSL_REDIRECT = True -SECURE_HSTS_SECONDS = 31536000 -SECURE_HSTS_INCLUDE_SUBDOMAINS = True -SECURE_HSTS_PRELOAD = True -SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https') - -# Session settings -SESSION_COOKIE_SECURE = True -CSRF_COOKIE_SECURE = True - -# Static files -STATICFILES_STORAGE = 'whitenoise.storage.CompressedManifestStaticFilesStorage' diff --git a/djinit/templates/config/urls.py-tpl b/djinit/templates/config/urls.py-tpl deleted file mode 100644 index 574294f..0000000 --- a/djinit/templates/config/urls.py-tpl +++ /dev/null @@ -1,103 +0,0 @@ -# @IF url_type == 'project' -"""generated with djinit""" - -from django.contrib import admin -from django.urls import path -# @IF include_api or include_apps -from django.urls import include -# @ENDIF -# @IF include_api -from django.conf import settings -from drf_spectacular.views import ( - SpectacularAPIView, - SpectacularSwaggerView, -) -from rest_framework_simplejwt.views import ( - TokenObtainPairView, - TokenRefreshView, - TokenBlacklistView, -) -# @ENDIF - -urlpatterns = [ - path("admin/", admin.site.urls), -# @IF include_api - # JWT tokens - path("token/", TokenObtainPairView.as_view(), name="token_obtain_pair"), - path("token/refresh/", TokenRefreshView.as_view(), name="token_refresh"), - path("token/blacklist/", TokenBlacklistView.as_view(), name="token_blacklist"), -# @ENDIF -# @IF include_api and comment_out_api_url - # path("api/", include("[[ api_module ]].urls")), -# @ENDIF -# @IF include_api and not comment_out_api_url - path("api/", include("[[ api_module ]].urls")), -# @ENDIF -# @IF include_apps - # App URLs -# @LOOP app in app_names - path("", include("[[ app ]].urls")), -# @ENDLOOP -# @ENDIF -] -# @IF include_api - -# Don't show schema in production -if settings.DEBUG: - urlpatterns += [ - path("schema/", SpectacularAPIView.as_view(), name="schema"), - path("docs/", SpectacularSwaggerView.as_view(url_name="schema")), - ] -# @ENDIF -# @ENDIF -# @IF url_type == 'api_root' -from django.urls import include, path - -app_name = "[[ app_name ]]" - -urlpatterns = [ - path("[[ version ]]/", include("[[ api_module ]].[[ version ]].urls")), -] -# @ENDIF -# @IF url_type == 'api_version' -from django.urls import include, path - -app_name = "[[ app_name ]]" - -urlpatterns = [ -# @LOOP app in app_list - path("[[ app ]]/", include("[[ app_module ]].[[ app ]].urls")), -# @ENDLOOP -] -# @ENDIF -# @IF url_type == 'drf_router' -from rest_framework.routers import DefaultRouter -# @IF has_viewset -from [[ app_module ]].views.[[ view_file ]] import [[ viewset_name ]] -# @ENDIF -# @IF has_app_name - -app_name = "[[ app_name ]]" -# @ENDIF - -router = DefaultRouter() -# @IF has_viewset -router.register(r"[[ router_prefix ]]", [[ viewset_name ]], basename="[[ basename ]]") -# @ENDIF - -urlpatterns = [ -# @IF has_include - path("", include(router.urls)), -# @ENDIF -] -# @IF not has_include -urlpatterns = router.urls -# @ENDIF -# @ENDIF -# @IF url_type == 'component' -from django.urls import path - -urlpatterns = [ - # Add your URL patterns here -] -# @ENDIF diff --git a/djinit/templates/config/wsgi.py-tpl b/djinit/templates/config/wsgi.py-tpl deleted file mode 100644 index 421456d..0000000 --- a/djinit/templates/config/wsgi.py-tpl +++ /dev/null @@ -1,12 +0,0 @@ -"""generated with djinit""" - -import os -import environ -from django.core.wsgi import get_wsgi_application - -env = environ.Env() -environ.Env.read_env() - -os.environ.setdefault("DJANGO_SETTINGS_MODULE", env("DJANGO_SETTINGS_MODULE", default="[[ project_name ]].settings.production")) - -application = get_wsgi_application() diff --git a/djinit/templates/presets/predefined/apps/generic/models.py-tpl b/djinit/templates/presets/predefined/apps/generic/models.py-tpl deleted file mode 100644 index bbae956..0000000 --- a/djinit/templates/presets/predefined/apps/generic/models.py-tpl +++ /dev/null @@ -1,18 +0,0 @@ -from django.db import models - - -class [[ model_class_name ]](models.Model): - """[[ model_class_name ]] model.""" - - # Add your fields here - name = models.CharField(max_length=255) - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - verbose_name = "[[ model_class_name ]]" - verbose_name_plural = "[[ model_class_name ]]s" - ordering = ["-created_at"] - - def __str__(self): - return self.name diff --git a/djinit/templates/presets/predefined/apps/generic/serializers.py-tpl b/djinit/templates/presets/predefined/apps/generic/serializers.py-tpl deleted file mode 100644 index 30b7189..0000000 --- a/djinit/templates/presets/predefined/apps/generic/serializers.py-tpl +++ /dev/null @@ -1,11 +0,0 @@ -from rest_framework import serializers -from [[ app_module ]].models.[[ app_name ]] import [[ model_class_name ]] - - -class [[ model_class_name ]]Serializer(serializers.ModelSerializer): - """Serializer for [[ model_class_name ]] model.""" - - class Meta: - model = [[ model_class_name ]] - fields = "__all__" - read_only_fields = ["id", "created_at", "updated_at"] diff --git a/djinit/templates/presets/predefined/apps/generic/services.py-tpl b/djinit/templates/presets/predefined/apps/generic/services.py-tpl deleted file mode 100644 index de45859..0000000 --- a/djinit/templates/presets/predefined/apps/generic/services.py-tpl +++ /dev/null @@ -1,36 +0,0 @@ -from [[ app_module ]].models.[[ app_name ]] import [[ model_class_name ]] - - -class [[ model_class_name ]]Service: - """Service class for [[ model_class_name ]] business logic.""" - - @staticmethod - def get_all(): - """Get all [[ model_class_name ]] instances.""" - return [[ model_class_name ]].objects.all() - - @staticmethod - def get_by_id(id): - """Get [[ model_class_name ]] by ID.""" - try: - return [[ model_class_name ]].objects.get(id=id) - except [[ model_class_name ]].DoesNotExist: - return None - - @staticmethod - def create(data): - """Create a new [[ model_class_name ]] instance.""" - return [[ model_class_name ]].objects.create(**data) - - @staticmethod - def update(instance, data): - """Update an existing [[ model_class_name ]] instance.""" - for key, value in data.items(): - setattr(instance, key, value) - instance.save() - return instance - - @staticmethod - def delete(instance): - """Delete a [[ model_class_name ]] instance.""" - instance.delete() diff --git a/djinit/templates/presets/predefined/apps/generic/tests.py-tpl b/djinit/templates/presets/predefined/apps/generic/tests.py-tpl deleted file mode 100644 index 8dc7a7e..0000000 --- a/djinit/templates/presets/predefined/apps/generic/tests.py-tpl +++ /dev/null @@ -1,55 +0,0 @@ -from rest_framework.test import APITestCase -from rest_framework import status -from django.contrib.auth import get_user_model - -from [[ app_module ]].models.[[ app_name ]] import [[ model_class_name ]] - -User = get_user_model() - - -class [[ model_class_name ]]APITestCase(APITestCase): - """Test cases for [[ model_class_name ]] API endpoints.""" - - def setUp(self): - """Set up test data.""" - self.user = User.objects.create_user( - username="testuser", password="testpass123" - ) - self.client.force_authenticate(user=self.user) - self.test_data = {"name": "Test [[ model_class_name ]]"} - - def test_create_[[ app_name ]](self): - """Test creating a [[ model_class_name ]].""" - response = self.client.post("/api/v1/[[ app_name ]]/", self.test_data) - self.assertEqual(response.status_code, status.HTTP_201_CREATED) - self.assertEqual([[ model_class_name ]].objects.count(), 1) - - def test_list_[[ app_name ]]s(self): - """Test listing all [[ model_class_name ]]s.""" - [[ model_class_name ]].objects.create(**self.test_data) - response = self.client.get("/api/v1/[[ app_name ]]/") - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(len(response.data), 1) - - def test_retrieve_[[ app_name ]](self): - """Test retrieving a single [[ model_class_name ]].""" - instance = [[ model_class_name ]].objects.create(**self.test_data) - response = self.client.get(f"/api/v1/[[ app_name ]]/{instance.id}/") - self.assertEqual(response.status_code, status.HTTP_200_OK) - self.assertEqual(response.data["name"], self.test_data["name"]) - - def test_update_[[ app_name ]](self): - """Test updating a [[ model_class_name ]].""" - instance = [[ model_class_name ]].objects.create(**self.test_data) - updated_data = {"name": "Updated [[ model_class_name ]]"} - response = self.client.patch(f"/api/v1/[[ app_name ]]/{instance.id}/", updated_data) - self.assertEqual(response.status_code, status.HTTP_200_OK) - instance.refresh_from_db() - self.assertEqual(instance.name, updated_data["name"]) - - def test_delete_[[ app_name ]](self): - """Test deleting a [[ model_class_name ]].""" - instance = [[ model_class_name ]].objects.create(**self.test_data) - response = self.client.delete(f"/api/v1/[[ app_name ]]/{instance.id}/") - self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT) - self.assertEqual([[ model_class_name ]].objects.count(), 0) diff --git a/djinit/templates/presets/predefined/apps/generic/views.py-tpl b/djinit/templates/presets/predefined/apps/generic/views.py-tpl deleted file mode 100644 index ef85cf5..0000000 --- a/djinit/templates/presets/predefined/apps/generic/views.py-tpl +++ /dev/null @@ -1,62 +0,0 @@ -from rest_framework import viewsets, status -from rest_framework.response import Response -from rest_framework.permissions import IsAuthenticated - -from [[ app_module ]].models.[[ app_name ]] import [[ model_class_name ]] -from [[ app_module ]].serializers.[[ app_name ]]_serializer import [[ model_class_name ]]Serializer -from [[ app_module ]].services.[[ app_name ]]_service import [[ model_class_name ]]Service - - -class [[ model_class_name ]]ViewSet(viewsets.ModelViewSet): - """ViewSet for [[ model_class_name ]] CRUD operations.""" - - queryset = [[ model_class_name ]].objects.all() - serializer_class = [[ model_class_name ]]Serializer - permission_classes = [IsAuthenticated] - - def list(self, request): - """List all [[ model_class_name ]] instances.""" - instances = [[ model_class_name ]]Service.get_all() - serializer = self.get_serializer(instances, many=True) - return Response(serializer.data) - - def retrieve(self, request, pk=None): - """Retrieve a single [[ model_class_name ]] instance.""" - instance = [[ model_class_name ]]Service.get_by_id(pk) - if not instance: - return Response( - {"error": "[[ model_class_name ]] not found"}, status=status.HTTP_404_NOT_FOUND - ) - serializer = self.get_serializer(instance) - return Response(serializer.data) - - def create(self, request): - """Create a new [[ model_class_name ]] instance.""" - serializer = self.get_serializer(data=request.data) - serializer.is_valid(raise_exception=True) - instance = [[ model_class_name ]]Service.create(serializer.validated_data) - return Response( - self.get_serializer(instance).data, status=status.HTTP_201_CREATED - ) - - def update(self, request, pk=None): - """Update an existing [[ model_class_name ]] instance.""" - instance = [[ model_class_name ]]Service.get_by_id(pk) - if not instance: - return Response( - {"error": "[[ model_class_name ]] not found"}, status=status.HTTP_404_NOT_FOUND - ) - serializer = self.get_serializer(instance, data=request.data, partial=True) - serializer.is_valid(raise_exception=True) - updated_instance = [[ model_class_name ]]Service.update(instance, serializer.validated_data) - return Response(self.get_serializer(updated_instance).data) - - def destroy(self, request, pk=None): - """Delete a [[ model_class_name ]] instance.""" - instance = [[ model_class_name ]]Service.get_by_id(pk) - if not instance: - return Response( - {"error": "[[ model_class_name ]] not found"}, status=status.HTTP_404_NOT_FOUND - ) - [[ model_class_name ]]Service.delete(instance) - return Response(status=status.HTTP_204_NO_CONTENT) diff --git a/djinit/templates/presets/predefined/apps/users/models.py-tpl b/djinit/templates/presets/predefined/apps/users/models.py-tpl deleted file mode 100644 index f6236bd..0000000 --- a/djinit/templates/presets/predefined/apps/users/models.py-tpl +++ /dev/null @@ -1,9 +0,0 @@ -from django.contrib.auth.models import AbstractUser -from django.db import models - - -class User(AbstractUser): - """Custom user model extending Django's AbstractUser.""" - - # Add custom fields here if needed - pass diff --git a/djinit/templates/presets/predefined/apps/users/serializers.py-tpl b/djinit/templates/presets/predefined/apps/users/serializers.py-tpl deleted file mode 100644 index d7a4f40..0000000 --- a/djinit/templates/presets/predefined/apps/users/serializers.py-tpl +++ /dev/null @@ -1,9 +0,0 @@ -from rest_framework import serializers - -from apps.users.models.user import User - - -class UserSerializer(serializers.ModelSerializer): - class Meta: - model = User - fields = ["id", "username", "email", "first_name", "last_name"] diff --git a/djinit/templates/presets/predefined/apps/users/services.py-tpl b/djinit/templates/presets/predefined/apps/users/services.py-tpl deleted file mode 100644 index 036060b..0000000 --- a/djinit/templates/presets/predefined/apps/users/services.py-tpl +++ /dev/null @@ -1,10 +0,0 @@ -from typing import Optional - -from apps.users.models.user import User - - -def get_user_by_id(user_id: int) -> Optional[User]: - try: - return User.objects.get(id=user_id) - except User.DoesNotExist: - return None diff --git a/djinit/templates/presets/predefined/apps/users/tests.py-tpl b/djinit/templates/presets/predefined/apps/users/tests.py-tpl deleted file mode 100644 index 1bde766..0000000 --- a/djinit/templates/presets/predefined/apps/users/tests.py-tpl +++ /dev/null @@ -1,12 +0,0 @@ -import pytest -from django.urls import reverse -from rest_framework.test import APIClient - - -@pytest.mark.django_db -def test_users_list_empty(): - client = APIClient() - url = reverse("v1:users-list") - response = client.get(url) - assert response.status_code == 200 - assert response.json() == [] diff --git a/djinit/templates/presets/predefined/apps/users/views.py-tpl b/djinit/templates/presets/predefined/apps/users/views.py-tpl deleted file mode 100644 index 8db2347..0000000 --- a/djinit/templates/presets/predefined/apps/users/views.py-tpl +++ /dev/null @@ -1,13 +0,0 @@ -from rest_framework import status, viewsets -from rest_framework.response import Response - -from apps.users.models.user import User -from apps.users.serializers.user_serializer import UserSerializer - - -class UserViewSet(viewsets.ReadOnlyModelViewSet): - queryset = User.objects.all() - serializer_class = UserSerializer - - def list(self, request, *args, **kwargs): - return super().list(request, *args, **kwargs) diff --git a/djinit/templates/presets/predefined/core/exceptions.py-tpl b/djinit/templates/presets/predefined/core/exceptions.py-tpl deleted file mode 100644 index bb426d3..0000000 --- a/djinit/templates/presets/predefined/core/exceptions.py-tpl +++ /dev/null @@ -1,5 +0,0 @@ -class ApplicationError(Exception): - """Base application exception.""" - - def __init__(self, message: str): - super().__init__(message) diff --git a/djinit/templates/presets/predefined/core/middleware/request_logger.py-tpl b/djinit/templates/presets/predefined/core/middleware/request_logger.py-tpl deleted file mode 100644 index d922ad1..0000000 --- a/djinit/templates/presets/predefined/core/middleware/request_logger.py-tpl +++ /dev/null @@ -1,14 +0,0 @@ -import logging - - -logger = logging.getLogger(__name__) - - -class RequestLoggerMiddleware: - def __init__(self, get_response): - self.get_response = get_response - - def __call__(self, request): - logger.info("%s %s", request.method, request.path) - response = self.get_response(request) - return response diff --git a/djinit/templates/presets/predefined/core/mixins/timestamped_model.py-tpl b/djinit/templates/presets/predefined/core/mixins/timestamped_model.py-tpl deleted file mode 100644 index 6b2e70e..0000000 --- a/djinit/templates/presets/predefined/core/mixins/timestamped_model.py-tpl +++ /dev/null @@ -1,9 +0,0 @@ -from django.db import models - - -class TimestampedModel(models.Model): - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - abstract = True diff --git a/djinit/templates/presets/predefined/core/utils/responses.py-tpl b/djinit/templates/presets/predefined/core/utils/responses.py-tpl deleted file mode 100644 index f4b5269..0000000 --- a/djinit/templates/presets/predefined/core/utils/responses.py-tpl +++ /dev/null @@ -1,17 +0,0 @@ -# @IF include_header -"""generated with djinit""" - -# @ENDIF -from rest_framework.response import Response - - -def success(data=None, status_code=200): -# @IF include_docstrings """Return a successful response.""" -# @ENDIF - return Response({"success": True, "data": data}, status=status_code) - - -def error(message, status_code=400): -# @IF include_docstrings """Return an error response.""" -# @ENDIF - return Response({"success": False, "message": message}, status=status_code) diff --git a/djinit/templates/presets/unified/apps/core/apps.py-tpl b/djinit/templates/presets/unified/apps/core/apps.py-tpl deleted file mode 100644 index 1d202ca..0000000 --- a/djinit/templates/presets/unified/apps/core/apps.py-tpl +++ /dev/null @@ -1,8 +0,0 @@ -"""generated with djinit""" - -from django.apps import AppConfig - - -class CoreConfig(AppConfig): - default_auto_field = "django.db.models.BigAutoField" - name = "apps.core" diff --git a/djinit/templates/presets/unified/apps/core/models/__init__.py-tpl b/djinit/templates/presets/unified/apps/core/models/__init__.py-tpl deleted file mode 100644 index 89b2eb6..0000000 --- a/djinit/templates/presets/unified/apps/core/models/__init__.py-tpl +++ /dev/null @@ -1,4 +0,0 @@ -from .base import AbstractBaseModel -from .mixins import TimestampedModel - -__all__ = ["AbstractBaseModel", "TimestampedModel"] diff --git a/djinit/templates/presets/unified/apps/core/models/base.py-tpl b/djinit/templates/presets/unified/apps/core/models/base.py-tpl deleted file mode 100644 index a3970f9..0000000 --- a/djinit/templates/presets/unified/apps/core/models/base.py-tpl +++ /dev/null @@ -1,13 +0,0 @@ -"""generated with djinit""" - -from django.db import models - - -class AbstractBaseModel(models.Model): - """Abstract base model with common fields.""" - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - abstract = True diff --git a/djinit/templates/presets/unified/apps/core/models/mixins.py-tpl b/djinit/templates/presets/unified/apps/core/models/mixins.py-tpl deleted file mode 100644 index fe40544..0000000 --- a/djinit/templates/presets/unified/apps/core/models/mixins.py-tpl +++ /dev/null @@ -1,13 +0,0 @@ -"""generated with djinit""" - -from django.db import models - - -class TimestampedModel(models.Model): - """Mixin for models that need timestamp fields.""" - - created_at = models.DateTimeField(auto_now_add=True) - updated_at = models.DateTimeField(auto_now=True) - - class Meta: - abstract = True diff --git a/djinit/templates/presets/unified/apps/core/utils/__init__.py-tpl b/djinit/templates/presets/unified/apps/core/utils/__init__.py-tpl deleted file mode 100644 index 155f5b4..0000000 --- a/djinit/templates/presets/unified/apps/core/utils/__init__.py-tpl +++ /dev/null @@ -1,3 +0,0 @@ -from .responses import success, error - -__all__ = ["success", "error"] diff --git a/djinit/templates/project/ci/github_actions-tpl b/djinit/templates/project/ci/github_actions-tpl deleted file mode 100644 index 5217107..0000000 --- a/djinit/templates/project/ci/github_actions-tpl +++ /dev/null @@ -1,109 +0,0 @@ -name: Django CI - -on: - push: - branches: [ main, develop ] - pull_request: - branches: [ main, develop ] - -jobs: - test: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: ["3.12", "3.13"] - - services: - postgres: - image: postgres:15 - env: - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - POSTGRES_DB: test_db - options: >- - --health-cmd pg_isready - --health-interval 10s - --health-timeout 5s - --health-retries 5 - ports: - - 5432:5432 - - steps: - - uses: actions/checkout@v4 - - - name: Set up Python {{ '{{ matrix.python-version }}' }} - uses: actions/setup-python@v5 - with: - python-version: {{ '{{ matrix.python-version }}' }} - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - version: "latest" - - - name: Install dependencies - run: uv sync - - - name: Run linting - run: uv run ruff check . - - - name: Format check - run: uv run ruff format --check . - - - name: Set up PostgreSQL - env: - DB_NAME: test_db - DB_USER: postgres - DB_PASSWORD: postgres - DB_HOST: localhost - DB_PORT: 5432 - run: | - echo "PostgreSQL is ready" - - - name: Run Django tests - env: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - DB_NAME: test_db - DB_USER: postgres - DB_PASSWORD: postgres - DB_HOST: localhost - DB_PORT: 5432 - run: | - uv run python manage.py check - uv run python manage.py test - - - name: Check migrations - env: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - DB_NAME: test_db - DB_USER: postgres - DB_PASSWORD: postgres - DB_HOST: localhost - DB_PORT: 5432 - run: | - uv run python manage.py makemigrations --check --dry-run - - security: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Python - uses: actions/setup-python@v5 - with: - python-version: "3.13" - - - name: Install uv - uses: astral-sh/setup-uv@v4 - with: - version: "latest" - - - name: Install dependencies - run: uv sync - - - name: Run security check - run: uv run python manage.py check --deploy diff --git a/djinit/templates/project/ci/gitlab_ci-tpl b/djinit/templates/project/ci/gitlab_ci-tpl deleted file mode 100644 index 3d3bc61..0000000 --- a/djinit/templates/project/ci/gitlab_ci-tpl +++ /dev/null @@ -1,133 +0,0 @@ -# GitLab CI/CD configuration for [[ project_name ]] - -stages: - - test - - lint - - security - -variables: - POSTGRES_DB: test_db - POSTGRES_USER: postgres - POSTGRES_PASSWORD: postgres - DATABASE_URL: "postgresql://postgres:postgres@postgres:5432/test_db" - -# Use Docker-in-Docker -services: - - postgres:15 - -before_script: - - python --version - - pip install uv - - uv sync - -# Lint stage -lint: - stage: lint - image: python:3.13 - script: - - uv run ruff check . - - uv run ruff format --check . - only: - - branches - - merge_requests - -# Test stage -test: - stage: test - image: python:3.13 - variables: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - script: - - uv run python manage.py check - - uv run python manage.py migrate - - uv run python manage.py test - only: - - branches - - merge_requests - -# Multiple Python versions -test:python310: - stage: test - image: python:3.10 - variables: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - script: - - pip install uv - - uv sync - - uv run python manage.py check - - uv run python manage.py migrate - - uv run python manage.py test - only: - - branches - - merge_requests - -test:python311: - stage: test - image: python:3.11 - variables: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - script: - - pip install uv - - uv sync - - uv run python manage.py check - - uv run python manage.py migrate - - uv run python manage.py test - only: - - branches - - merge_requests - -test:python312: - stage: test - image: python:3.12 - variables: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - script: - - pip install uv - - uv sync - - uv run python manage.py check - - uv run python manage.py migrate - - uv run python manage.py test - only: - - branches - - merge_requests - -test:python313: - stage: test - image: python:3.13 - variables: - DJANGO_SETTINGS_MODULE: [[ module_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - ALLOWED_HOSTS: localhost - script: - - pip install uv - - uv sync - - uv run python manage.py check - - uv run python manage.py migrate - - uv run python manage.py test - only: - - branches - - merge_requests - -# Security check -security: - stage: security - image: python:3.13 - variables: - DJANGO_SETTINGS_MODULE: [[ project_name ]].settings.development - SECRET_KEY: test-secret-key-for-ci - script: - - pip install uv - - uv sync - - uv run python manage.py check --deploy - - uv run python manage.py validate_templates - only: - - main - - develop diff --git a/djinit/templates/project/env_sample-tpl b/djinit/templates/project/env_sample-tpl deleted file mode 100644 index 382da28..0000000 --- a/djinit/templates/project/env_sample-tpl +++ /dev/null @@ -1,32 +0,0 @@ -# Django settings -DJANGO_SETTINGS_MODULE=[[ project_name ]].settings.development -SECRET_KEY= your-secret-key -ALLOWED_HOSTS=api.your-domain.com,www.your-domain.com - -# @IF use_database_url -# Database URL (recommended for production) -# @IF database_type == 'mysql' -DATABASE_URL=mysql://user:password@localhost:3306/[[ project_name ]] -# @ELSE -DATABASE_URL=postgres://user:password@localhost:5432/[[ project_name ]] -# @ENDIF -# @ELSE -# Database (individual parameters) -DB_NAME= -DB_USER= -DB_PASSWORD= -DB_HOST= -DB_PORT= -# @ENDIF - -# Frontend URL -FRONTEND_URL=http://frontend.your-domain.com - -# Email settings -EMAIL_HOST= -EMAIL_PORT= -EMAIL_USE_TLS= -EMAIL_HOST_USER= -EMAIL_HOST_PASSWORD= -DEFAULT_FROM_EMAIL= -SERVER_EMAIL= diff --git a/djinit/templates/project/gitignore-tpl b/djinit/templates/project/gitignore-tpl deleted file mode 100644 index 2b5243c..0000000 --- a/djinit/templates/project/gitignore-tpl +++ /dev/null @@ -1,93 +0,0 @@ -#--------------------------------------------------# -# The following was generated by djinit: # -#--------------------------------------------------# - -# Python -*.py[cod] -*$py.class -*.so -__pycache__/ -*.egg-info/ -dist/ -build/ -.eggs/ -*.egg - -# Django -*.log -local_settings.py -db.sqlite3 -db.sqlite3-journal -*.sqlite3 - -# Environment -.env -.venv -env/ -venv/ -ENV/ -env.bak/ -venv.bak/ - -# IDEs -.vscode/ -.idea/ -*.swp -*.swo -*~ -.project -.pydevproject -.settings/ -.ropeproject/ - -# OS -.DS_Store -*.DS_Store -Thumbs.db -desktop.ini - -# Django specific -media/ -staticfiles/ -staticfiles/ -static_root/ -/static/ - -# Testing -.coverage -htmlcov/ -.pytest_cache/ -.tox/ -coverage.xml -*.cover -.hypothesis/ -.cache - -# Logs -logs/ -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* - -# Node modules (if using frontend tools) -node_modules/ - -# Secret keys -secret.txt -secrets.json - -# Jupyter Notebook -.ipynb_checkpoints - -# Backup files -*.bak -*.tmp -*~ - -# Database -*.db -*.sql - -# Cloud -.cloud diff --git a/djinit/templates/project/init.py-tpl b/djinit/templates/project/init.py-tpl deleted file mode 100644 index e69de29..0000000 diff --git a/djinit/templates/project/justfile-tpl b/djinit/templates/project/justfile-tpl deleted file mode 100644 index 127e77d..0000000 --- a/djinit/templates/project/justfile-tpl +++ /dev/null @@ -1,219 +0,0 @@ -# Justfile for [[ project_name ]] -# Task runner for Django development -# Install just: https://github.com/casey/just - -# Default task: show available commands -default: - @just --list - -# Run development server -dev: - uv run python manage.py runserver - -# Run development server with custom host and port -dev-server HOST="0.0.0.0" PORT="8000": - uv run python manage.py runserver {{ '{{' }}HOST{{ '}}' }}:{{ '{{' }}PORT{{ '}}' }} - -# Create migrations for all apps -makemigrations: - uv run python manage.py makemigrations - -# Create migrations for specific app -makemigrations-app APP: - uv run python manage.py makemigrations {{ '{{' }}APP{{ '}}' }} - -# Run all migrations -migrate: - uv run python manage.py migrate - -# Reset database (delete all migrations) -reset-db: - uv run python manage.py flush --noinput - uv run python manage.py migrate - -# Create superuser -createsuperuser: - uv run python manage.py createsuperuser - -# Collect static files -collectstatic: - uv run python manage.py collectstatic --noinput - -# Run Django shell -shell: - uv run python manage.py shell - -# Run Django shell plus (IPython) -shell-plus: - uv run python manage.py shell_plus - -# Run tests -test: - uv run python manage.py test - -# Run tests with coverage -test-coverage: - uv run pytest --cov=. --cov-report=html --cov-report=term - -# Lint code with ruff -lint: - uv run ruff check . - -# Format code with ruff -format: - uv run ruff format . - -# Lint and format code -style: - uv run ruff check . - uv run ruff format . - -# Check security issues -check: - uv run python manage.py check - -# Check security issues (production settings) -check-deploy: - uv run python manage.py check --deploy - -# Show all database migrations status -showmigrations: - uv run python manage.py showmigrations - -# Sync dependencies (uv equivalent of pip freeze) -requirements: - uv pip compile - -# Run all linting and checks -ci: - uv run ruff check . - uv run ruff format --check . - uv run python manage.py check - -# Start interactive shell -shell-ipython: - uv run python manage.py shell_plus - -# Clear all cache -clear-cache: - uv run python manage.py clear_cache - -# Show Django version -version: - uv run python manage.py version - -# Run database shell -dbshell: - uv run python manage.py dbshell - -# Start production server with gunicorn -server: - uv run gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:8000 - -# Start production server with gunicorn workers -server-prod WORKERS="4": - uv run gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:8000 --workers {{ '{{' }}WORKERS{{ '}}' }} - -# Start production server with gunicorn and reload on file changes -server-watch: - uv run gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:8000 --reload - -# Clean Python cache files -clean: - find . -type d -name "__pycache__" -exec rm -rf {} + - find . -type f -name "*.pyc" -delete - find . -type f -name "*.pyo" -delete - find . -type f -name ".coverage" -delete - find . -type d -name "*.egg-info" -exec rm -rf {} + - rm -rf htmlcov/ - rm -rf .pytest_cache/ - -# Pin dependencies in pyproject.toml using versions from uv.lock, keeping >= and extras -pin-deps: - #!/usr/bin/env -S uv run python - import tomllib, re - from pathlib import Path - - lock = Path("uv.lock") - if not lock.exists(): - print("uv.lock not found — run `uv sync` first") - raise SystemExit(0) - - data = tomllib.loads(lock.read_text()) - packages = {p["name"].lower(): p["version"] for p in data.get("package", [])} - - py = Path("pyproject.toml") - lines = py.read_text().splitlines() - - pattern = re.compile(r'^(\s*)"([^"]+)"(,?)') - - out = [] - for line in lines: - m = pattern.match(line) - if not m: - out.append(line) - continue - - indent, dep, comma = m.groups() - - base = dep - extras = "" - operator = ">=" - version = None - - # extras: django[postgres] - if "[" in base and "]" in base: - before, after = base.split("[", 1) - extras = "[" + after.split("]")[0] + "]" - base = before - - # detect >= or == - if ">=" in dep: - operator = ">=" - base, version = dep.split(">=") - base = base.strip() - elif "==" in dep: - operator = "==" - base, version = dep.split("==") - base = base.strip() - else: - base = dep - - base_lower = base.lower() - new_version = packages.get(base_lower) - - if new_version: - new_dep = f'{base}{extras}{operator}{new_version}' - line = f'{indent}"{new_dep}"{comma}' - - out.append(line) - - py.write_text("\n".join(out) + "\n") - print("Pinned dependencies (>= preserved, extras preserved).") - - -# Setup project for development (using uv) -setup: - uv sync - just pin-deps - uv run python manage.py migrate - uv run python manage.py createsuperuser - -# Complete setup including static files -setup-complete: - uv sync - uv run python manage.py migrate - uv run python manage.py collectstatic --noinput - uv run python manage.py createsuperuser - -# Install a new package -install PACKAGE: - uv add {{ '{{' }}PACKAGE{{ '}}' }} - -# Install a dev package -install-dev PACKAGE: - uv add --dev {{ '{{' }}PACKAGE{{ '}}' }} - -# Remove a package -remove PACKAGE: - uv remove {{ '{{' }}PACKAGE{{ '}}' }} diff --git a/djinit/templates/project/manage.py-tpl b/djinit/templates/project/manage.py-tpl deleted file mode 100644 index ba6f5c7..0000000 --- a/djinit/templates/project/manage.py-tpl +++ /dev/null @@ -1,32 +0,0 @@ -#!/usr/bin/env python - -"""generated with djinit""" - -"""Django's command-line utility for administrative tasks.""" -import os -import sys - -import environ - - -def main(): - """Run administrative tasks.""" - os.environ.setdefault("DJANGO_SETTINGS_MODULE", os.getenv("DJANGO_SETTINGS_MODULE", "[[ project_name ]].settings.production")) - - try: - from django.core.management import execute_from_command_line - except ImportError as exc: - raise ImportError( - "Couldn't import Django. Are you sure it's installed and " - "available on your PYTHONPATH environment variable? Did you " - "forget to activate a virtual environment?" - ) from exc - execute_from_command_line(sys.argv) - - -if __name__ == "__main__": - env = environ.Env() - # Read .env file, if it exists - environ.Env.read_env() - - main() diff --git a/djinit/templates/project/procfile-tpl b/djinit/templates/project/procfile-tpl deleted file mode 100644 index fc01178..0000000 --- a/djinit/templates/project/procfile-tpl +++ /dev/null @@ -1,20 +0,0 @@ -# Procfile for [[ project_name ]] -# Used for deploying to PaaS platforms like Heroku, Railway, Render, etc. - -# Web server process (using Gunicorn) -# Adjust workers based on your needs: (2 x CPU cores) + 1 -web: gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:$PORT --workers 2 --timeout 120 --access-logfile - --error-logfile - --log-level info - -# Alternative web server configurations (uncomment to use): -# web: gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:$PORT --workers 4 --threads 2 --timeout 120 -# web: gunicorn [[ project_name ]].wsgi:application --bind 0.0.0.0:$PORT --workers 2 --worker-class gevent --worker-connections 1000 --timeout 120 - -# Release task (runs migrations before deployment) -release: python manage.py migrate --noinput && python manage.py collectstatic --noinput - -# Uncomment below to run scheduled tasks (if using Celery) -# worker: celery -A [[ project_name ]] worker --loglevel=info -# beat: celery -A [[ project_name ]] beat --loglevel=info - -# Development server (for local testing with Foreman/Overmind) -# web: python manage.py runserver 0.0.0.0:$PORT diff --git a/djinit/templates/project/pyproject.toml-tpl b/djinit/templates/project/pyproject.toml-tpl deleted file mode 100644 index e9e49a3..0000000 --- a/djinit/templates/project/pyproject.toml-tpl +++ /dev/null @@ -1,46 +0,0 @@ -[project] -name = "[[ package_name ]]" -version = "0.1.0" -description = "" -readme = "README.md" -requires-python = ">=3.13" -license = { text = "MIT" } -dependencies = [ - "django", - "django-environ", - "django-jazzmin", - "djangorestframework", - "djangorestframework-simplejwt", - "drf-spectacular", - "django-cors-headers", - "whitenoise", -# @IF database_type == 'mysql' - "mysqlclient", -# @ENDIF -# @IF database_type == 'postgresql' - "psycopg2-binary", -# @ENDIF - "gunicorn", -] - -[tool.ruff] -line-length = 88 -target-version = "py38" - -[tool.ruff.lint] -select = [ - "E", # pycodestyle errors - "W", # pycodestyle warnings - "F", # pyflakes - "I", # isort - "B", # flake8-bugbear - "C4", # flake8-comprehensions - "UP", # pyupgrade -] -ignore = [ - "E501", # line too long, handled by formatter - "B008", # do not perform function calls in argument defaults -] - -[tool.ruff.lint.isort] -known-first-party = ["[[ project_name ]]"] diff --git a/djinit/templates/project/readme.md-tpl b/djinit/templates/project/readme.md-tpl deleted file mode 100644 index 9c28632..0000000 --- a/djinit/templates/project/readme.md-tpl +++ /dev/null @@ -1,201 +0,0 @@ -# [[ project_name ]] - -A Django project folder structure is generated with [djinitx/djinit/dj](https://github.com/S4NKALP/djinit). - -## Features - -- Modern project structure with environment-specific settings -- Pre-configured REST API with JWT authentication -- Essential dependencies and utilities -- Production-ready configuration - -## Setup - -### Using Just (Recommended) - -1. Set environment variables in `.env` file - -2. Run setup (installs dependencies, runs migrations, creates superuser): - ```bash - just setup - ``` - -3. Start development server: - ```bash - just dev - ``` - -### Traditional Method - -1. Install dependencies: - ```bash - pip install -r requirements.txt - ``` - -2. Set environment variables in `.env` file - -3. Run migrations: - ```bash - python manage.py migrate - ``` - -4. Create superuser: - ```bash - python manage.py createsuperuser - ``` - -5. Start development server: - ```bash - python manage.py runserver - ``` - -## Available Commands - -Run `just` to see all available commands, including: - -- `just dev` - Run development server -- `just migrate` - Run migrations -- `just makemigrations` - Create migrations -- `just createsuperuser` - Create superuser -- `just test` - Run tests -- `just lint` - Lint code -- `just format` - Format code -- `just shell` - Django shell -- `just clean` - Clean cache files -- `just install ` - Install package -- `just remove ` - Remove package -- `just server` - Run production server -- `just ci` - Run all linting and checks -- `just test-coverage` - Run tests with coverage - -## Project Structure - -``` -# @IF predefined_structure -[[ project_name ]]/ -├── [[ module_name ]]/ -│ ├── settings/ -│ │ ├── base.py -│ │ ├── development.py -│ │ └── production.py -│ ├── urls.py -│ ├── wsgi.py -│ └── asgi.py -├── apps/ -│ ├── users/ -│ │ ├── apps.py -│ │ ├── models/ -│ │ │ └── user.py -│ │ ├── serializers/ -│ │ │ └── user_serializer.py -│ │ ├── services/ -│ │ │ └── user_service.py -│ │ ├── views/ -│ │ │ └── user_view.py -│ │ ├── urls.py -│ │ └── tests/ -│ │ └── test_user_api.py -│ └── core/ -│ ├── utils/ -│ │ └── responses.py -│ ├── mixins/ -│ │ └── timestamped_model.py -│ ├── exceptions.py -│ └── middleware/ -│ └── request_logger.py -├── api/ -│ ├── __init__.py -│ ├── urls.py -│ └── v1/ -│ ├── __init__.py -│ └── urls.py -├── manage.py -├── requirements.txt -├── pyproject.toml -├── uv.lock -├── .env.sample -├── justfile -├── Procfile -├── runtime.txt -└── README.md -# @ELSEIF unified_structure -[[ project_name ]]/ -├── apps/ -│ ├── admin/ -│ │ └── __init__.py -│ ├── api/ -│ │ ├── __init__.py -│ │ ├── urls.py -│ │ └── v1/ -│ │ ├── __init__.py -│ │ └── urls.py -│ ├── models/ -│ │ └── __init__.py -│ ├── serializers/ -│ │ └── __init__.py -│ ├── tests/ -│ │ └── __init__.py -│ ├── urls/ -│ │ └── __init__.py -│ └── views/ -│ └── __init__.py -├── core/ -│ ├── asgi.py -│ ├── __init__.py -│ ├── settings/ -│ │ ├── base.py -│ │ ├── development.py -│ │ ├── __init__.py -│ │ └── production.py -│ ├── urls.py -│ └── wsgi.py -├── manage.py -├── requirements.txt -├── pyproject.toml -├── uv.lock -├── .env.sample -├── justfile -├── Procfile -├── runtime.txt -└── README.md -# @ELSE -[[ project_name ]]/ -├── [[ module_name ]]/ -│ ├── settings/ -│ │ ├── base.py -│ │ ├── development.py -│ │ └── production.py -│ ├── admin/ -│ ├── api/ # API endpoints organized by model -│ │ ├── user/ # Example: if you have a User model -│ │ │ ├── views.py -│ │ │ ├── serializers.py -│ │ │ └── urls.py -│ │ └── urls.py -│ ├── models/ # Django models -│ ├── tests/ -│ ├── urls.py -│ ├── wsgi.py -│ └── asgi.py -├── manage.py -├── requirements.txt -├── pyproject.toml -├── uv.lock -├── .env.sample -└── README.md - -**Note:** For the single folder layout, organize your API endpoints by model name under the `api/` directory. -For example, if you have a `User` model in `models/user.py`, create: -- `api/user/views.py` - API views for User -- `api/user/serializers.py` - Serializers for User -- `api/user/urls.py` - URL patterns for User endpoints - -See the README files in `api/` and `models/` directories for more details. -# @ENDIF -``` - -## API Documentation - -When running in development mode, API documentation is available at: -- Swagger UI: http://localhost:8000/docs/ -- Schema: http://localhost:8000/schema/ diff --git a/djinit/templates/project/requirements-tpl b/djinit/templates/project/requirements-tpl deleted file mode 100644 index cb48ff9..0000000 --- a/djinit/templates/project/requirements-tpl +++ /dev/null @@ -1,19 +0,0 @@ -#--------------------------------------------------# -# The following was generated by djinit: # -#--------------------------------------------------# - -Django -django-environ -django-jazzmin -djangorestframework -djangorestframework_simplejwt -drf-spectacular -django-cors-headers -whitenoise -# @IF database_type == 'mysql' -mysqlclient -# @ELSE -psycopg[binary] -# @ENDIF -gunicorn -dj-database-url # @IF use_database_url diff --git a/djinit/templates/project/runtime_txt-tpl b/djinit/templates/project/runtime_txt-tpl deleted file mode 100644 index 34ffefa..0000000 --- a/djinit/templates/project/runtime_txt-tpl +++ /dev/null @@ -1 +0,0 @@ -python-[[ python_version ]]