Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Django custom commands not found when built as .exe #2285

Open
dcabrero opened this issue Mar 6, 2024 · 1 comment
Open

Django custom commands not found when built as .exe #2285

dcabrero opened this issue Mar 6, 2024 · 1 comment

Comments

@dcabrero
Copy link

dcabrero commented Mar 6, 2024

Describe the bug
When adding a Django custom admin command, it wont show or run by default when app is packaged.

To Reproduce
Start a basic boilerplate django app, then add a command:
https://docs.djangoproject.com/en/4.2/howto/custom-management-commands/

Expected behavior
After using setup.py build, should be able to run exename.exe custom_command

Desktop (please complete the following information):

  • Platform information: Windows 10 pro x64
  • Python 3.10.10
  • cx_Freeze version: 6.15.15
  • Django: 4.2.1

Additional context
I got it working by monkey patching this by importing this on my manage.py script.


def __override_commands():
    import django.utils.autoreload
    import django.core.management

    original_commands = django.core.management.get_commands()

    def _get_commands():

        original_commands
        commands = original_commands 
        commands['test_command'] = 'test_app'
        return commands

    _old_restart_with_reloader = django.utils.autoreload.restart_with_reloader

    def _restart_with_reloader(*args):
        import sys
        a0 = sys.argv.pop(0)
        try:
            return _old_restart_with_reloader(*args)
        finally:
            sys.argv.insert(0, a0)

    django.core.management.get_commands = _get_commands
    django.utils.autoreload.restart_with_reloader = _restart_with_reloader

__override_commands()
del __override_commands

And making sure that setup.py has the command.py file in its build_options:

build_options = {
    'packages': ['django', 'corsheaders', 'whitenoise', 'core_app', 'test_app'],
    'includes': ['test_app.management.commands.test_command'],
    'excludes': []
}

Hope it helps :]

@dcabrero
Copy link
Author

dcabrero commented Mar 6, 2024

Ok, after a few hours I noticed that even if were adding the package 'test_app', not all of its contents were going into the lib folder.

I'm now using this in my setup.py to get all the contents of a list of main folders that are part of a django project:

def get_py_files(directories):
    py_files = []
    for directory in directories:
        for root, dirs, files in os.walk(directory):
            for file in files:
                if file.endswith('.py'):
                    relative_root = root.replace(directory, '').lstrip(os.sep)
                    dotted_path = relative_root.replace(os.sep, '.')
                    if dotted_path:
                        py_files.append(f"{directory}.{dotted_path}.{file[:-3]}")
                    else:
                        py_files.append(f"{directory}.{file[:-3]}")
    return py_files 

Probably not the cleanest way, but it works and auto detects the command without the previous solution I did before.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant