From 33bb6c299ef6ea4a4c07c4c4fe9ab37f01e72fbb Mon Sep 17 00:00:00 2001 From: S4NKALP Date: Wed, 29 Oct 2025 12:21:35 +0545 Subject: [PATCH] refactor: improve code structure and UI messages for better clarity --- .github/dependabot.yml | 1 - .github/workflows/ci.yml | 1 - .github/workflows/codeql.yml | 1 - .github/workflows/dependabot-auto-merge.yml | 1 - .github/workflows/pre-commit.yml | 1 - .pre-commit-config.yaml | 1 - ruff.toml | 1 - setup.py | 1 - src/scripts/app_generator.py | 22 ++-- src/scripts/cicd_config_generator.py | 4 +- src/scripts/command_handler.py | 12 +- src/scripts/console_ui.py | 139 ++++++-------------- src/scripts/deployment_files_generator.py | 6 +- src/scripts/files.py | 2 +- src/scripts/input_handler.py | 12 +- src/scripts/project.py | 5 +- src/scripts/secretkey_generator.py | 4 +- src/templates/env_sample.j2 | 2 +- src/templates/routes.j2 | 2 +- 19 files changed, 71 insertions(+), 147 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 7bbac87..9fe84dd 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -16,4 +16,3 @@ updates: - "dependencies" - "python" open-pull-requests-limit: 10 - diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f8db5a5..4d0ec1f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,4 +44,3 @@ jobs: - name: Test console script entry point run: | djinit --help - diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 8ad65b3..fcf8a68 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -31,4 +31,3 @@ jobs: - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v3 - diff --git a/.github/workflows/dependabot-auto-merge.yml b/.github/workflows/dependabot-auto-merge.yml index 9a2c695..aaf6277 100644 --- a/.github/workflows/dependabot-auto-merge.yml +++ b/.github/workflows/dependabot-auto-merge.yml @@ -40,4 +40,3 @@ jobs: with: token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN || secrets.GITHUB_TOKEN }} merge-method: squash - diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml index b218c82..23b86c4 100644 --- a/.github/workflows/pre-commit.yml +++ b/.github/workflows/pre-commit.yml @@ -27,4 +27,3 @@ jobs: - name: Run pre-commit run: | pre-commit run --all-files - diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 059217a..2555428 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -18,4 +18,3 @@ repos: - id: end-of-file-fixer - id: check-yaml - id: check-added-large-files - diff --git a/ruff.toml b/ruff.toml index 226cfb7..9adb00f 100644 --- a/ruff.toml +++ b/ruff.toml @@ -25,4 +25,3 @@ ignore = [ indent-style = "space" skip-magic-trailing-comma = false line-ending = "auto" - diff --git a/setup.py b/setup.py index 373c5c2..fd25ee8 100644 --- a/setup.py +++ b/setup.py @@ -17,7 +17,6 @@ setup( "rich>=14.2.0", "jinja2>=3.1.0", # "django<=5.2.7", - ], entry_points={"console_scripts": ["djinit=src.generator:main"]}, classifiers=[ diff --git a/src/scripts/app_generator.py b/src/scripts/app_generator.py index c6e640e..a572566 100644 --- a/src/scripts/app_generator.py +++ b/src/scripts/app_generator.py @@ -5,7 +5,6 @@ Handles creation of Django apps and updating settings. import os import subprocess -import sys from typing import Optional from src.scripts.console_ui import UIFormatter @@ -60,17 +59,12 @@ class AppManager: if not os.path.exists(manage_py_path): UIFormatter.print_error("Could not find manage.py file in project root") return False - + # Create app in the correct location with change_cwd(apps_base_dir): UIFormatter.print_info(f"Creating app '{self.app_name}' in directory: {os.getcwd()}") - - result = subprocess.run( - ["django-admin", "startapp", self.app_name], - capture_output=True, - text=True, - check=True - ) + + subprocess.run(["django-admin", "startapp", self.app_name], capture_output=True, text=True, check=True) UIFormatter.print_success(f"Created Django app '{self.app_name}' in {apps_base_dir}") return True @@ -99,14 +93,14 @@ class AppManager: app_module_path = f"{nested_dir}.{self.app_name}" else: app_module_path = self.app_name - + UIFormatter.print_info(f"App module path: {app_module_path}") # Check if app is already in USER_DEFINED_APPS section specifically lines = content.split("\n") in_user_apps = False app_already_exists = False - + for line in lines: if "USER_DEFINED_APPS" in line and "=" in line: in_user_apps = True @@ -197,7 +191,7 @@ class AppManager: # Step 2: try to infer nested_dir from USER_DEFINED_APPS in base.py try: if settings_base_path and os.path.exists(settings_base_path): - with open(settings_base_path, "r") as f: + with open(settings_base_path) as f: base_content = f.read() # Find lines inside USER_DEFINED_APPS and extract first dotted app in_user_apps = False @@ -209,7 +203,7 @@ class AppManager: break if in_user_apps: line_stripped = line.strip().strip(",") - if line_stripped.startswith("\"") or line_stripped.startswith("'"): + if line_stripped.startswith('"') or line_stripped.startswith("'"): app_label = line_stripped.strip("\"'") if "." in app_label: prefix = app_label.split(".", 1)[0] @@ -243,7 +237,7 @@ class AppManager: # Detect project structure to get correct app path is_nested, nested_dir, apps_base_dir = self._detect_project_structure() app_path = os.path.join(apps_base_dir, self.app_name) - + # Create serializers.py context = {"app_name": self.app_name} serializers_content = template_engine.render_template("serializers.j2", context) diff --git a/src/scripts/cicd_config_generator.py b/src/scripts/cicd_config_generator.py index a22ed9a..3410281 100644 --- a/src/scripts/cicd_config_generator.py +++ b/src/scripts/cicd_config_generator.py @@ -25,7 +25,7 @@ class CICDConfigGenerator: create_file_with_content( workflow_file, workflow_content, - f"Created Github Actions workflow ({workflow_file})", + "Created Github Actions workflow (ci.yml)", ) return True @@ -36,6 +36,6 @@ class CICDConfigGenerator: create_file_with_content( ".gitlab-ci.yml", gitlab_ci_content, - f"Created GitLab CI configuration (.gitlab-ci.yml)", + "Created GitLab CI configuration (.gitlab-ci.yml)", ) return True diff --git a/src/scripts/command_handler.py b/src/scripts/command_handler.py index 2710c81..e76bba3 100644 --- a/src/scripts/command_handler.py +++ b/src/scripts/command_handler.py @@ -26,9 +26,7 @@ def parse_arguments() -> argparse.Namespace: secret_parser.add_argument("--length", type=int, default=50, help="Length of each secret key") # App command - app_parser = subparsers.add_parser( - "app", help="Create one or more Django apps (comma or space separated)" - ) + app_parser = subparsers.add_parser("app", help="Create one or more Django apps (comma or space separated)") app_parser.add_argument( "app_name", nargs="+", @@ -132,15 +130,11 @@ def handle_app_command(args: argparse.Namespace) -> None: instructions = Text() instructions.append("🚀 Next Steps:\n", style=UIColors.ACCENT) - instructions.append( - "1. The app(s) have been added to INSTALLED_APPS in settings/base.py\n" - ) + instructions.append("1. The app(s) have been added to INSTALLED_APPS in settings/base.py\n") instructions.append("2. Create your models in each app's models.py\n") instructions.append("3. Run migrations: python manage.py makemigrations\n") instructions.append("4. Apply migrations: python manage.py migrate\n") - instructions.append( - "5. Create views, serializers and routes(URLs) for your app(s)\n" - ) + instructions.append("5. Create views, serializers and routes(URLs) for your app(s)\n") console.print(Panel(instructions, title="💡 What's Next", border_style="green")) UIFormatter.print_info("") diff --git a/src/scripts/console_ui.py b/src/scripts/console_ui.py index f2338ae..7346822 100644 --- a/src/scripts/console_ui.py +++ b/src/scripts/console_ui.py @@ -3,22 +3,23 @@ Console UI utilities for djinit. Provides enhanced styling, formatting, and user interface components. """ -from typing import List, Optional, Dict, Any +from contextlib import contextmanager +from typing import Any, Dict, List, Optional + +from rich import box from rich.console import Console +from rich.panel import Panel from rich.progress import ( + BarColumn, Progress, SpinnerColumn, - BarColumn, TaskProgressColumn, TextColumn, TimeRemainingColumn, ) from rich.syntax import Syntax -from rich.text import Text -from rich.panel import Panel from rich.table import Table -from rich import box -from contextlib import contextmanager +from rich.text import Text console = Console() @@ -65,37 +66,25 @@ class UIFormatter: @staticmethod def print_success(message: str, icon: str = Icons.SUCCESS): - console.print( - f"[{UIColors.SUCCESS}]{icon}[/{UIColors.SUCCESS}] [bold]{message}[/bold]" - ) + console.print(f"[{UIColors.SUCCESS}]{icon}[/{UIColors.SUCCESS}] [bold]{message}[/bold]") @staticmethod - def print_error( - message: str, icon: str = Icons.ERROR, details: Optional[str] = None - ): + def print_error(message: str, icon: str = Icons.ERROR, details: Optional[str] = None): """Print error message with optional details""" - console.print( - f"[{UIColors.ERROR}]{icon}[/{UIColors.ERROR}] [bold]{message}[/bold]" - ) + console.print(f"[{UIColors.ERROR}]{icon}[/{UIColors.ERROR}] [bold]{message}[/bold]") if details: console.print(f" [dim]{details}[/dim]") @staticmethod def print_warning(message: str, icon: str = Icons.WARNING): - console.print( - f"[{UIColors.WARNING}]{icon}[/{UIColors.WARNING}] [bold]{message}[/bold]" - ) + console.print(f"[{UIColors.WARNING}]{icon}[/{UIColors.WARNING}] [bold]{message}[/bold]") @staticmethod def print_info(message: str, icon: str = Icons.INFO): - console.print( - f"[{UIColors.INFO}]{icon}[/{UIColors.INFO}] [bold]{message}[/bold]" - ) + console.print(f"[{UIColors.INFO}]{icon}[/{UIColors.INFO}] [bold]{message}[/bold]") @staticmethod - def print_step( - step_number: int, total_steps: int, description: str, icon: str = "" - ): + def print_step(step_number: int, total_steps: int, description: str, icon: str = ""): """Print step information with enhanced progress indicator""" icon_str = f"{icon} " if icon else "" percentage = int((step_number / total_steps) * 100) @@ -116,9 +105,7 @@ class UIFormatter: ) @staticmethod - def create_live_progress( - description: str = "Setup Progress", total_steps: int = 100 - ): + def create_live_progress(description: str = "Setup Progress", total_steps: int = 100): """Create a live progress display that updates in place""" progress = Progress( SpinnerColumn(), @@ -152,10 +139,8 @@ class UIFormatter: @staticmethod def print_feature_list(features: List[str], icon: str = Icons.STAR): """Print a styled feature list with custom icons""" - for i, feature in enumerate(features, 1): - console.print( - f"[{UIColors.ACCENT}] {icon}[/{UIColors.ACCENT}] [bold]{feature}[/bold]" - ) + for _i, feature in enumerate(features, 1): + console.print(f"[{UIColors.ACCENT}] {icon}[/{UIColors.ACCENT}] [bold]{feature}[/bold]") @staticmethod def print_numbered_list(items: List[str], start: int = 1): @@ -166,9 +151,7 @@ class UIFormatter: console.print(f" [dim]{prefix}[/dim] [dim]{i}.[/dim] {item}") @staticmethod - def print_tree_item( - text: str, is_last: bool = False, indent: int = 0, icon: str = "" - ): + def print_tree_item(text: str, is_last: bool = False, indent: int = 0, icon: str = ""): """Print a tree-style item""" prefix = "└─" if is_last else "├─" icon_str = f"{icon} " if icon else "" @@ -183,15 +166,11 @@ class UIFormatter: line_numbers: bool = True, ): """Print code with syntax highlighting and customization""" - syntax = Syntax( - code, language, theme=theme, line_numbers=line_numbers, word_wrap=True - ) + syntax = Syntax(code, language, theme=theme, line_numbers=line_numbers, word_wrap=True) console.print(syntax) @staticmethod - def print_panel( - content: str, title: str = "", style: str = "cyan", border_style: str = "blue" - ): + def print_panel(content: str, title: str = "", style: str = "cyan", border_style: str = "blue"): """Print content in a styled panel""" panel = Panel( content, @@ -208,9 +187,7 @@ class UIFormatter: if not data: return - table = Table( - title=title, box=box.ROUNDED, show_header=True, header_style="bold cyan" - ) + table = Table(title=title, box=box.ROUNDED, show_header=True, header_style="bold cyan") # Add columns from first row for key in data[0].keys(): @@ -245,9 +222,7 @@ class UIFormatter: style=UIColors.MUTED, ) welcome_text.append(" Repository: ", style=UIColors.MUTED) - welcome_text.append( - "https://github.com/S4NKALP/djinit\n", style="blue underline" - ) + welcome_text.append("https://github.com/S4NKALP/djinit\n", style="blue underline") welcome_text.append(" License: MIT\n", style=UIColors.MUTED) return welcome_text @@ -266,63 +241,39 @@ class UIFormatter: if success: # Success header console.print(f"[bold green]{'═' * 70}[/bold green]") - console.print( - f"[bold green]{f'{Icons.PARTY} SETUP COMPLETE! {Icons.PARTY}'.center(70)}[/bold green]" - ) + console.print(f"[bold green]{f'{Icons.PARTY} SETUP COMPLETE! {Icons.PARTY}'.center(70)}[/bold green]") console.print(f"[bold green]{'═' * 70}[/bold green]\n") # Duration if provided if duration: - console.print( - f"[dim]{Icons.CLOCK} Completed in {duration:.2f} seconds[/dim]\n" - ) + console.print(f"[dim]{Icons.CLOCK} Completed in {duration:.2f} seconds[/dim]\n") # Project details console.print(f"[bold cyan]{Icons.TARGET} Project Details:[/bold cyan]") console.print(" [dim]│[/dim]") - console.print( - f" [dim]├─[/dim] [bold]Directory:[/bold] [white]{project_dir}[/white]" - ) - console.print( - f" [dim]├─[/dim] [bold]Project:[/bold] [white]{project_name}[/white]" - ) - console.print( - f" [dim]└─[/dim] [bold]Apps:[/bold] [white]{', '.join(app_names)}[/white]" - ) + console.print(f" [dim]├─[/dim] [bold]Directory:[/bold] [white]{project_dir}[/white]") + console.print(f" [dim]├─[/dim] [bold]Project:[/bold] [white]{project_name}[/white]") + console.print(f" [dim]└─[/dim] [bold]Apps:[/bold] [white]{', '.join(app_names)}[/white]") console.print() # Next steps console.print(f"[bold cyan]{Icons.ROCKET} Next Steps:[/bold cyan]") console.print(" [dim]│[/dim]") + console.print(" [dim]├─[/dim] [dim]1.[/dim] Navigate to your project directory") + console.print(" [dim]├─[/dim] [dim]2.[/dim] Set environment variables in .env file") + console.print(" [dim]├─[/dim] [dim]3.[/dim] Run migrations: [cyan]python manage.py migrate[/cyan]") console.print( - f" [dim]├─[/dim] [dim]1.[/dim] Navigate to your project directory" - ) - console.print( - f" [dim]├─[/dim] [dim]2.[/dim] Set environment variables in .env file" - ) - console.print( - f" [dim]├─[/dim] [dim]3.[/dim] Run migrations: [cyan]python manage.py migrate[/cyan]" - ) - console.print( - f" [dim]├─[/dim] [dim]4.[/dim] Create superuser: [cyan]python manage.py createsuperuser[/cyan]" - ) - console.print( - f" [dim]└─[/dim] [dim]5.[/dim] Start server: [cyan]python manage.py runserver[/cyan]" + " [dim]├─[/dim] [dim]4.[/dim] Create superuser: [cyan]python manage.py createsuperuser[/cyan]" ) + console.print(" [dim]└─[/dim] [dim]5.[/dim] Start server: [cyan]python manage.py runserver[/cyan]") console.print() # Useful URLs console.print(f"[bold cyan]{Icons.LINK} Useful URLs:[/bold cyan]") console.print(" [dim]│[/dim]") - console.print( - f" [dim]├─[/dim] Admin: [blue]http://localhost:8000/admin/[/blue]" - ) - console.print( - f" [dim]├─[/dim] API Docs: [blue]http://localhost:8000/docs/[/blue]" - ) - console.print( - f" [dim]└─[/dim] API Schema: [blue]http://localhost:8000/schema/[/blue]" - ) + console.print(" [dim]├─[/dim] Admin: [blue]http://localhost:8000/admin/[/blue]") + console.print(" [dim]├─[/dim] API Docs: [blue]http://localhost:8000/docs/[/blue]") + console.print(" [dim]└─[/dim] API Schema: [blue]http://localhost:8000/schema/[/blue]") console.print() console.print(f"[bold green]{'═' * 70}[/bold green]\n") @@ -336,22 +287,18 @@ class UIFormatter: console.print("[red]The setup process encountered an error.[/red]\n") # Troubleshooting - console.print( - f"[bold yellow]{Icons.MAGNIFIER} Troubleshooting Tips:[/bold yellow]" - ) + console.print(f"[bold yellow]{Icons.MAGNIFIER} Troubleshooting Tips:[/bold yellow]") console.print(" [dim]│[/dim]") - console.print(f" [dim]├─[/dim] Check the error messages above") - console.print(f" [dim]├─[/dim] Ensure you have write permissions") - console.print(f" [dim]├─[/dim] Verify Django is installed correctly") - console.print(f" [dim]└─[/dim] Try running with elevated permissions") + console.print(" [dim]├─[/dim] Check the error messages above") + console.print(" [dim]├─[/dim] Ensure you have write permissions") + console.print(" [dim]├─[/dim] Verify Django is installed correctly") + console.print(" [dim]└─[/dim] Try running with elevated permissions") console.print() console.print(f"[bold red]{'═' * 70}[/bold red]\n") @staticmethod - def create_progress_display( - description: str = "Processing", total_steps: int = 100 - ): + def create_progress_display(description: str = "Processing", total_steps: int = 100): """Create a comprehensive live progress display""" progress = Progress( SpinnerColumn(), @@ -374,11 +321,7 @@ class UIFormatter: def confirm(prompt: str, default: bool = True) -> bool: """Display a confirmation prompt""" default_str = "Y/n" if default else "y/N" - response = ( - console.input(f"[bold cyan]?[/bold cyan] {prompt} [{default_str}]: ") - .strip() - .lower() - ) + response = console.input(f"[bold cyan]?[/bold cyan] {prompt} [{default_str}]: ").strip().lower() if not response: return default diff --git a/src/scripts/deployment_files_generator.py b/src/scripts/deployment_files_generator.py index 90f7d87..b9f191b 100644 --- a/src/scripts/deployment_files_generator.py +++ b/src/scripts/deployment_files_generator.py @@ -77,7 +77,7 @@ tmp_upload_dir = None create_file_with_content( "gunicorn_config.py", gunicorn_config_content, - f"Created gunicorn_config.py with Gunicorn configuration", + "Created gunicorn_config.py with Gunicorn configuration", ) return True @@ -88,7 +88,7 @@ tmp_upload_dir = None create_file_with_content( "runtime.txt", runtime_content, - f"Created runtime.txt with Python version specification", + "Created runtime.txt with Python version specification", ) return True @@ -113,6 +113,6 @@ cmd = "gunicorn {self.project_name}.wsgi:application --bind 0.0.0.0:$PORT" create_file_with_content( "nixpacks.toml", nixpacks_content, - f"Created nixpacks.toml for Nixpacks deployment", + "Created nixpacks.toml for Nixpacks deployment", ) return True diff --git a/src/scripts/files.py b/src/scripts/files.py index fe85789..205efed 100644 --- a/src/scripts/files.py +++ b/src/scripts/files.py @@ -53,7 +53,7 @@ class FileManager: with change_cwd(self.project_root): context = { "project_name": self.project_name, - "use_database_url": self.metadata.get("use_database_url", True) + "use_database_url": self.metadata.get("use_database_url", True), } env_content = template_engine.render_template("env_sample.j2", context) return create_file_with_content( diff --git a/src/scripts/input_handler.py b/src/scripts/input_handler.py index dae7ac4..07c5e59 100644 --- a/src/scripts/input_handler.py +++ b/src/scripts/input_handler.py @@ -203,8 +203,12 @@ class InputCollector: """Ask whether to create nested Django apps and get directory name if yes.""" UIFormatter.print_separator() console.print(f"\n[{UIColors.INFO}]Apps Layout[/{UIColors.INFO}]\n") - console.print(f"[{UIColors.MUTED}]Do you want to place apps inside a package directory (e.g., 'apps/')?[/{UIColors.MUTED}]") - console.print(f"[{UIColors.MUTED}]If yes, we'll create that directory as a Python package and generate apps inside it.[/{UIColors.MUTED}]") + console.print( + f"[{UIColors.MUTED}]Do you want to place apps inside a package directory (e.g., 'apps/')?[/{UIColors.MUTED}]" + ) + console.print( + f"[{UIColors.MUTED}]If yes, we'll create that directory as a Python package and generate apps inside it.[/{UIColors.MUTED}]" + ) console.print() console.print(f"[{UIColors.HIGHLIGHT}]Nested Django apps? (y/N):[/{UIColors.HIGHLIGHT}] ", end="") @@ -270,7 +274,7 @@ class CharReader: # Fallback try: return msvcrt.getch().lower() - except: + except Exception: return "" @staticmethod @@ -364,7 +368,7 @@ def confirm_setup(project_dir: str, project_name: str, app_names: list, metadata console.print(f"[{UIColors.HIGHLIGHT}]CI/CD:[/{UIColors.HIGHLIGHT}] {cicd_choices}") # Show database configuration - db_config = "DATABASE_URL" if metadata.get('use_database_url', True) else "Individual parameters" + db_config = "DATABASE_URL" if metadata.get("use_database_url", True) else "Individual parameters" console.print(f"[{UIColors.HIGHLIGHT}]Database Config:[/{UIColors.HIGHLIGHT}] {db_config}") console.print() diff --git a/src/scripts/project.py b/src/scripts/project.py index 257d0dd..220699f 100644 --- a/src/scripts/project.py +++ b/src/scripts/project.py @@ -3,6 +3,7 @@ Project management for djinit. Handles creation of Django projects and apps. """ +import importlib.util import os import subprocess import sys @@ -65,9 +66,7 @@ class ProjectManager: return True def _ensure_django_installed(self) -> None: - try: - import django - except ImportError: + if importlib.util.find_spec("django") is None: subprocess.run( [sys.executable, "-m", "pip", "install", "--upgrade", "django", "-q"], check=True, diff --git a/src/scripts/secretkey_generator.py b/src/scripts/secretkey_generator.py index 6f72e14..4194d21 100644 --- a/src/scripts/secretkey_generator.py +++ b/src/scripts/secretkey_generator.py @@ -27,9 +27,7 @@ def generate_multiple_keys(count: int = 3, length: int = 50) -> list[str]: def display_secret_keys(keys: list[str]) -> None: - table = Table( - title="🔐 Django Secret Keys", show_header=True, header_style="bold blue" - ) + table = Table(title="🔐 Django Secret Keys", show_header=True, header_style="bold blue") table.add_column("Environment", style="cyan", no_wrap=True) table.add_column("Secret Key", style="dim") diff --git a/src/templates/env_sample.j2 b/src/templates/env_sample.j2 index 7edee66..135d06b 100644 --- a/src/templates/env_sample.j2 +++ b/src/templates/env_sample.j2 @@ -20,4 +20,4 @@ EMAIL_HOST= EMAIL_PORT= EMAIL_USE_TLS= EMAIL_HOST_USER= -EMAIL_HOST_PASSWORD= \ No newline at end of file +EMAIL_HOST_PASSWORD= diff --git a/src/templates/routes.j2 b/src/templates/routes.j2 index 25a1203..c6ea465 100644 --- a/src/templates/routes.j2 +++ b/src/templates/routes.j2 @@ -13,4 +13,4 @@ router = DefaultRouter() # router.register(r'{{ app_name }}', views.{{ app_name|title }}ViewSet) # Get URL patterns -urlpatterns = router.urls \ No newline at end of file +urlpatterns = router.urls