I had to do this exact same thing. My solution was to use PyInstaller, which bundles all your packages and files into one neat distribution folder with an executable file in it.
First, look at this link for a tutorial. To be honest, this alone did not work for me, but it could for you. So I will document some things to look out for down below and continue from here as if it runs perfectly for you.
After PyInstaller runs on your manage.py file, it will create three new objects for you: a dist folder, a build folder, and a myAppName.spec file. In the dist folder is an executable for the project. To deploy this project to other places, the only thing needed is that dist folder (or even just the myAppName folder inside that). Simply zip it up and send it off.
The executable inside the dist folder does not run just by clicking on it though, it still requires you to type python manage.py runserver
. To get around this, I made a shortcut to the executable and modified it's target. So if your project's path is C:\path\to\proj
, the target of the shortcut will be C:\path\to\proj runserver
. This should allow you to double click the shortcut and run the local server. If you also wanted to open a web browser on the same click, make a batch file. If you don't like having the console open, try TrayIt.
If you want to re-run PyInstaller on your project, get rid of those dist and build folders for speed, but keep that .SPEC file and run pyinstaller on that instead. It can help you be more specific about the process if you care.
Issues to look out for:
As mentioned above, when I ran PyInstaller on my Django app I had a few of problems to work through.
- Whenever I ran my new executable, the console complained about "Module not found" errors. Here is my solution to these errors. I eventually had to add more hidden imports than my answer shows. Ask and you shall receive.
- PyInstaller was supposed to package all templates (html files), but it did not. I had to manually add all files to the
dist\myAppName\django\contrib\admin\templates
folder.
- PyInstaller was also supposed to grab all outside modules you use, but it did not. To use the missing module, I had to grab the module's folder from where I downloaded it and manually add it to my
dist/myAppName
folder. Just pasting it there worked out fine.
- PyInstaller is also supposed to get rid of unused imports, but it did not. I had to add a lot of modules to the
excludes
list in my .SPEC file so that my dist folder wasn't huge.
Let me know if your PyInstaller experiences are better than mine. I think my issues may have been isolated instances.