Virtualenv changes the current environment variables to use the correct python version. So the shebang in manage.py (/usr/bin/env python) will use the right version and installed packages.
The upside is you can change your python version & packages without changing hard coded paths to the virtual environment you want to use.
One of the big benefits of using virtualenv is that you can change the environment your code is running within. For example, if I want to test a new version of a package (or a new version of python altogether), I can create another virtual environment and "workon [newenvname]", ./manage.py runserver..., and test away.
It also follows the principal of least surprise. As a developer, if I run a python file, I generally expect it to use the python version in my environment, not some hard coded path. This is exactly why manage.py references python in the environment (/usr/bin/_env_) and not a direct path to the python executable.
It's easy to switch virtual environments and unexpected that I'd have to change code.
The upside is you can change your python version & packages without changing hard coded paths to the virtual environment you want to use.