I have developed several Django-CMS sites, e.g. Racing Tadpole, U R The Event Manager, Aquizzical and School Circle, and find myself frequently wanting to reuse pieces of the code. Of course, this is why Django has the concept of reusable apps, and has a good intro tutorial here.
I am going to embellish on that tutorial and show the actual steps I followed to go from no app, to a single package (possibly containing multiple apps) on the Python Package Index, pypi, that anyone can install with pip, that can be found by others on djangopackages, and with source code on github. I have already followed this process for cmsplugin-rt, which (in my humble opinion) contains lots of helpful Django-CMS plugins (particularly for Twitter Bootstrap) like buttons and a navbar, but also more generic plugins like Google fonts, Google analytics, Facebook and Twitter buttons. You can install this easily by typing:
pip install cmsplugin-rt
I now want to repeat that process for a new set of apps, which will include some global settings for Bootstrap.
- Create a dummy Django project with all the apps you are going to need (e.g. Django-CMS in my case).
- Write your app, starting with
python manage.py startapp myapp
- I have chosen to place this app one directory level down, i.e.
cmsapp_rt/bsglobals/, so that I can put more than one app in my package (
cmsapp_rt) and have them all installed by
pipin one go. Note you need to put an
__init__.pyfile in the
- Check your app works by including it in the
settings.pyfile, and typing
python manage.py runserver.
- My projects are in
~/Python/Projects. My approach is to create a directory like
~/Python/MyPackages, and in it create directories for each pip package. Note as far as I can tell, pip packages like to use hyphens instead of underscores. So I have a directory
- Following the Django tutorial, type:
mv ~/Python/Projects/dummy/cmsapp_rt ~/Python/MyPackages/cmsapp-rt/.
- Create the
MANIFEST.infiles in the
~/Python/MyPackages/cmsapp-rt/directory, as per the tutorial. Add the
docsdirectory. I also put in a
CHANGESfile (and add it to the
MANIFEST.infile too). Note if you have any fixtures, you need to add them to the
MANIFEST.infile in the same was as the templates. Feel free to base yours off mine if it helps.
- Create the
setup.pyfile. Note you can add a URL to github here, e.g.
url = 'https://github.com/RacingTadpole/cmsapp-rt'
I also used
from setuptools import setup setup(... find_packages packages = find_packages(), )
install_requires = [ 'django-singleton-admin', ],
and most importantly, add to the arguments to setup:
zip_safe = False,
which forces the package to be installed as real files, not a zipped up egg. Django seems to struggle with the zipped up eggs.
- Commit your work to git – add a
.gitignorefile which contains at least:
dist/ *.egg-info build/
Make yourself a new repository on Github. Then type:
git init git remote add origin https://github.com/user/reponame.git git add --all git commit -a -m "Initial commit" git push -u origin master
- You can build the package with
python setup.py sdist, as per the tutorial.
- Now it’s time to follow this guide from pypi. The only two things you need from this are:
python setup.py register python setup.py sdist bdist_wininst upload
The guide says you need to register on the site before that first command, but you can just run the command and it will do that for you. Also, I get the warning message below, but it doesn’t seem to matter (I have been using a Mac and a linux machine; maybe it is a problem for Windows?):
Warning: Can't read registry to find the necessary compiler setting Make sure that Python modules _winreg, win32api or win32con are installed.
- Whenever you make changes to the code, you only need to update README, CHANGES, the version number in
commitit to git (and
pushit to github), and type:
python setup.py sdist bdist_wininst upload
- At this point, you should be able to install the package using
pip install projectname
(or if you are only updating it, add
--updateon the end).
- With any luck, your dummy project will start to work again once you’ve done that, but this time, it will be drawing the app from your system’s packages, and any other project can do so too. (In practice, you will want to use virtualenv for this.)
- Finally, let django packages know about your app. This is very easy if you have already put your project on github – use the form here.
All done. I have followed this through and just published
cmsapp-rt in this way, which you can now install with
pip install cmsapp-rt
Please let me know if you have any suggestions or improvements!