The answer lies in a combination of two things:
- The shebang, the first line of a file.
- The permissions on the file, namely whether the executable flag is set or not.
Consider the first line of django-manage.py. On my system it is at /usr/local/bin/django-admin.py and the first line is:
#!/usr/bin/python2.7
And the permissions on the file:
-rwxr-xr-x 1 root root 127 Jan 9 13:38 /usr/local/bin/django-admin.py
The shebang tells my OS that I want to execute the file with the interpreter at /usr/bin/python2.7. The x characters in the permissions say that it is an executable file. I don't need to specify python beforehand, because the OS can figure out that stuff automatically from the above pieces of information.
Now for a freshly created manage.py, which I made by running django-admin.py startproject mysite, it looks like this:
#!/usr/bin/env python
And the permissions:
-rw-r--r-- 1 wim wim 249 Feb 17 17:33 manage.py
The shebang indicates to use whatever python interpreter my env is pointing at, so that part is in place already. But the file lacks executable permissions, so just running ./manage.py won't work (yet).
I can make it behave the same as django-manage.py by explicitly setting the executable flag using chmod +x manage.py. After that, you should see the x flags set when you do ls -l in the directory, and you should be able to run the file without specifying python beforehand.
Note: you do still have to use ./manage.py not just manage.py, this discrepancy is because django-admin.py lives in /usr/local/bin/ which is contained in PATH whereas the manage.py file likely doesn't. So we explicitly specify the path at the shell, where . refers to the current directory.
django-admin.pyshould have a shebang at the top that says to implicitly run the python interpreter.manage.pyis also auto-generated with the shebang. It does't have executable flag set, though.