Commits

Kenneth Love committed eebacd1

starting with django-party-pack

Comments (0)

Files changed (37)

+include README.rst
+recursive-include docs *
+recursive-include pollaxe/templates *
+==================
+django-party-pack
+==================
+
+Combining the Django Tutorial with Sphinx Docs, Django-Coverage, Coverage.py, and some notes on good practices
+
+Installation and documentation is at http://readthedocs.org/docs/django-party-pack/en/latest/
+
+
+# Makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line.
+SPHINXOPTS    =
+SPHINXBUILD   = sphinx-build
+PAPER         =
+BUILDDIR      = _build
+
+# Internal variables.
+PAPEROPT_a4     = -D latex_paper_size=a4
+PAPEROPT_letter = -D latex_paper_size=letter
+ALLSPHINXOPTS   = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) .
+
+.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest
+
+help:
+	@echo "Please use \`make <target>' where <target> is one of"
+	@echo "  html       to make standalone HTML files"
+	@echo "  dirhtml    to make HTML files named index.html in directories"
+	@echo "  singlehtml to make a single large HTML file"
+	@echo "  pickle     to make pickle files"
+	@echo "  json       to make JSON files"
+	@echo "  htmlhelp   to make HTML files and a HTML help project"
+	@echo "  qthelp     to make HTML files and a qthelp project"
+	@echo "  devhelp    to make HTML files and a Devhelp project"
+	@echo "  epub       to make an epub"
+	@echo "  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter"
+	@echo "  latexpdf   to make LaTeX files and run them through pdflatex"
+	@echo "  text       to make text files"
+	@echo "  man        to make manual pages"
+	@echo "  changes    to make an overview of all changed/added/deprecated items"
+	@echo "  linkcheck  to check all external links for integrity"
+	@echo "  doctest    to run all doctests embedded in the documentation (if enabled)"
+
+clean:
+	-rm -rf $(BUILDDIR)/*
+
+html:
+	$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/html."
+
+dirhtml:
+	$(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml
+	@echo
+	@echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml."
+
+singlehtml:
+	$(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml
+	@echo
+	@echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml."
+
+pickle:
+	$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle
+	@echo
+	@echo "Build finished; now you can process the pickle files."
+
+json:
+	$(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json
+	@echo
+	@echo "Build finished; now you can process the JSON files."
+
+htmlhelp:
+	$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp
+	@echo
+	@echo "Build finished; now you can run HTML Help Workshop with the" \
+	      ".hhp project file in $(BUILDDIR)/htmlhelp."
+
+qthelp:
+	$(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp
+	@echo
+	@echo "Build finished; now you can run "qcollectiongenerator" with the" \
+	      ".qhcp project file in $(BUILDDIR)/qthelp, like this:"
+	@echo "# qcollectiongenerator $(BUILDDIR)/qthelp/django-party-pack.qhcp"
+	@echo "To view the help file:"
+	@echo "# assistant -collectionFile $(BUILDDIR)/qthelp/django-party-pack.qhc"
+
+devhelp:
+	$(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp
+	@echo
+	@echo "Build finished."
+	@echo "To view the help file:"
+	@echo "# mkdir -p $$HOME/.local/share/devhelp/django-party-pack"
+	@echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/django-party-pack"
+	@echo "# devhelp"
+
+epub:
+	$(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub
+	@echo
+	@echo "Build finished. The epub file is in $(BUILDDIR)/epub."
+
+latex:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo
+	@echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex."
+	@echo "Run \`make' in that directory to run these through (pdf)latex" \
+	      "(use \`make latexpdf' here to do that automatically)."
+
+latexpdf:
+	$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex
+	@echo "Running LaTeX files through pdflatex..."
+	make -C $(BUILDDIR)/latex all-pdf
+	@echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex."
+
+text:
+	$(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text
+	@echo
+	@echo "Build finished. The text files are in $(BUILDDIR)/text."
+
+man:
+	$(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man
+	@echo
+	@echo "Build finished. The manual pages are in $(BUILDDIR)/man."
+
+changes:
+	$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes
+	@echo
+	@echo "The overview file is in $(BUILDDIR)/changes."
+
+linkcheck:
+	$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck
+	@echo
+	@echo "Link check complete; look for any errors in the above output " \
+	      "or in $(BUILDDIR)/linkcheck/output.txt."
+
+doctest:
+	$(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest
+	@echo "Testing of doctests in the sources finished, look at the " \
+	      "results in $(BUILDDIR)/doctest/output.txt."
+# -*- coding: utf-8 -*-
+#
+# django-party-pack documentation build configuration file, created by
+# sphinx-quickstart on Tue Jun 21 12:25:32 2011.
+#
+# This file is execfile()d with the current directory set to its containing dir.
+#
+# Note that not all possible configuration values are present in this
+# autogenerated file.
+#
+# All configuration values have a default; values that are commented out
+# serve to show the default.
+
+import sys, os
+
+# PYDANNY NOTE: Change 'pollaxe to whatever your project might be.'
+sys.path.insert(0, os.path.abspath('../pollaxe'))
+
+import settings
+from django.core.management import setup_environ
+setup_environ(settings)
+
+# -- General configuration -----------------------------------------------------
+
+# If your documentation needs a minimal Sphinx version, state it here.
+#needs_sphinx = '1.0'
+
+# Add any Sphinx extension module names here, as strings. They can be extensions
+# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
+extensions = ['sphinx.ext.autodoc', 'sphinx.ext.viewcode']
+
+# Add any paths that contain templates here, relative to this directory.
+templates_path = ['_templates']
+
+# The suffix of source filenames.
+source_suffix = '.rst'
+
+# The encoding of source files.
+#source_encoding = 'utf-8-sig'
+
+# The master toctree document.
+master_doc = 'index'
+
+# General information about the project.
+project = u'django-party-pack'
+copyright = u'2011, Daniel Greenfeld'
+
+# The version info for the project you're documenting, acts as replacement for
+# |version| and |release|, also used in various other places throughout the
+# built documents.
+#
+# The short X.Y version.
+version = '0.2.0'
+# The full version, including alpha/beta/rc tags.
+release = '0.2.0'
+
+# The language for content autogenerated by Sphinx. Refer to documentation
+# for a list of supported languages.
+#language = None
+
+# There are two options for replacing |today|: either, you set today to some
+# non-false value, then it is used:
+#today = ''
+# Else, today_fmt is used as the format for a strftime call.
+#today_fmt = '%B %d, %Y'
+
+# List of patterns, relative to source directory, that match files and
+# directories to ignore when looking for source files.
+exclude_patterns = ['_build']
+
+# The reST default role (used for this markup: `text`) to use for all documents.
+#default_role = None
+
+# If true, '()' will be appended to :func: etc. cross-reference text.
+#add_function_parentheses = True
+
+# If true, the current module name will be prepended to all description
+# unit titles (such as .. function::).
+#add_module_names = True
+
+# If true, sectionauthor and moduleauthor directives will be shown in the
+# output. They are ignored by default.
+#show_authors = False
+
+# The name of the Pygments (syntax highlighting) style to use.
+pygments_style = 'sphinx'
+
+# A list of ignored prefixes for module index sorting.
+#modindex_common_prefix = []
+
+
+# -- Options for HTML output ---------------------------------------------------
+
+# The theme to use for HTML and HTML Help pages.  See the documentation for
+# a list of builtin themes.
+html_theme = 'default'
+
+# Theme options are theme-specific and customize the look and feel of a theme
+# further.  For a list of options available for each theme, see the
+# documentation.
+#html_theme_options = {}
+
+# Add any paths that contain custom themes here, relative to this directory.
+#html_theme_path = []
+
+# The name for this set of Sphinx documents.  If None, it defaults to
+# "<project> v<release> documentation".
+#html_title = None
+
+# A shorter title for the navigation bar.  Default is the same as html_title.
+#html_short_title = None
+
+# The name of an image file (relative to this directory) to place at the top
+# of the sidebar.
+#html_logo = None
+
+# The name of an image file (within the static path) to use as favicon of the
+# docs.  This file should be a Windows icon file (.ico) being 16x16 or 32x32
+# pixels large.
+#html_favicon = None
+
+# Add any paths that contain custom static files (such as style sheets) here,
+# relative to this directory. They are copied after the builtin static files,
+# so a file named "default.css" will overwrite the builtin "default.css".
+html_static_path = ['_static']
+
+# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
+# using the given strftime format.
+#html_last_updated_fmt = '%b %d, %Y'
+
+# If true, SmartyPants will be used to convert quotes and dashes to
+# typographically correct entities.
+#html_use_smartypants = True
+
+# Custom sidebar templates, maps document names to template names.
+#html_sidebars = {}
+
+# Additional templates that should be rendered to pages, maps page names to
+# template names.
+#html_additional_pages = {}
+
+# If false, no module index is generated.
+#html_domain_indices = True
+
+# If false, no index is generated.
+#html_use_index = True
+
+# If true, the index is split into individual pages for each letter.
+#html_split_index = False
+
+# If true, links to the reST sources are added to the pages.
+#html_show_sourcelink = True
+
+# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
+#html_show_sphinx = True
+
+# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
+#html_show_copyright = True
+
+# If true, an OpenSearch description file will be output, and all pages will
+# contain a <link> tag referring to it.  The value of this option must be the
+# base URL from which the finished HTML is served.
+#html_use_opensearch = ''
+
+# This is the file name suffix for HTML files (e.g. ".xhtml").
+#html_file_suffix = None
+
+# Output file base name for HTML help builder.
+htmlhelp_basename = 'django-party-packdoc'
+
+
+# -- Options for LaTeX output --------------------------------------------------
+
+# The paper size ('letter' or 'a4').
+#latex_paper_size = 'letter'
+
+# The font size ('10pt', '11pt' or '12pt').
+#latex_font_size = '10pt'
+
+# Grouping the document tree into LaTeX files. List of tuples
+# (source start file, target name, title, author, documentclass [howto/manual]).
+latex_documents = [
+  ('index', 'django-party-pack.tex', u'django-party-pack Documentation',
+   u'Daniel Greenfeld', 'manual'),
+]
+
+# The name of an image file (relative to this directory) to place at the top of
+# the title page.
+#latex_logo = None
+
+# For "manual" documents, if this is true, then toplevel headings are parts,
+# not chapters.
+#latex_use_parts = False
+
+# If true, show page references after internal links.
+#latex_show_pagerefs = False
+
+# If true, show URL addresses after external links.
+#latex_show_urls = False
+
+# Additional stuff for the LaTeX preamble.
+#latex_preamble = ''
+
+# Documents to append as an appendix to all manuals.
+#latex_appendices = []
+
+# If false, no module index is generated.
+#latex_domain_indices = True
+
+
+# -- Options for manual page output --------------------------------------------
+
+# One entry per manual page. List of tuples
+# (source start file, name, description, authors, manual section).
+man_pages = [
+    ('index', 'django-party-pack', u'django-party-pack Documentation',
+     [u'Daniel Greenfeld'], 1)
+]

docs/confessions_of_joe_developer.rst

+Confessions of Joe Developer
+============================
+
+1. I'm stupid:
+    * Can't figure things out
+        * If I get stuck for more than 30 minutes:
+            * Find libraries that do it for me.
+            * Ask on Twitter for answers.
+            * SO is good, but watch out for trolls.
+            * IRC can be good, again, trolls.
+    * Can't remember things
+        * Documentation makes me look good.
+        * Docstrings are awesome.
+        * Learn you some REStructuredText
+        * Write down even the slide bullets.
+        * Sphinx makes me and my code look good.
+    * Ask the dumbest questions
+
+2. I'm lazy:
+    * Don't want to do anything twice
+        * If I write the same code twice, I stick it in a method.
+        * Then stick the function into a utils module.
+        * Then I put it up on Github so I don't lose it.
+    * Don't want to debug code that worked before
+        * Manually testing code by watching it run is hard...
+        * ... and boring ...
+        * ... and hence is error prone.
+        * Meaning you have to do more work.
+        * **Are you testing enough?**
+            * coverage.py is great
+            * django-coverage runs coverage.py for Django
+            * But you only want to test your own apps. Refer to code on Github for how.
+            * Look at how he does INSTALLED_APPS
+    * Don't want to upload ZIP files per documentation change
+
+3. Don't be smart and lazy
+
+4. Technical Debt
+    * Postponed activities:
+        * Documentation
+            * unshared knowledge
+        * Tests
+        * attending to TODO statements
+        * Code too confusing to be modified easily
+
+A positive trait good tech leads often look for is the ability to ask questions.
+
+http://bit.ly/audreyr-sphinx
+https://github.com/pydanny/django-party-pack/
+
+Q&A
+===
+
+1. Do you try to understand the 3rd party code or isolate it?
+    * Pip & Virtualenv to isolate it.

docs/contributors.rst

+.. _`contributors`:
+
+================
+Contributors
+================
+
+I didn't do this in a vacuum. This is built off of packages and libraries created by a huge number of incredible people. And everything on this was taught to me either on the job or by looking at other people's examples of how to do things. Here we go:
+
+* Audrey Roy for coming up with this idea and agreeing to marry me.
+* Aaron Kavlie, Geoffrey Jost, and Preston Holmes for helping organize things.
+* Chris Shenton for showing me that more notes are better - even if they seem stupid to take at the time.
+* Eric Holscher for rtfd.org
+* Evgany Fadeev for showing me how to work Sphinx autodoc.
+* Frank Wiles for general Django code cleanliness and inspiring the Cartwheel way.
+* Georg Brandl for Sphinx
+* George Song for django-coverage
+* Gisle Aas for the way django-coverage is implemented in this project
+* Jacob Kaplan-Moss for a culture of documentation plus schooling me personally hard on exceptions and writing better tests.
+* James Tauber and Alex Gaynor for settings.PROJECT_ROOT.
+* Nate Aune for teaching me that tests should be a story.
+* Ned Batchelder for coverage.py
+* Steve Holden for teaching me better skills explaining technical things in text.
+
+ If I miss anyone I apologize!

docs/conventions.rst

+==================
+Coding Conventions
+==================
+
+So we are all on the same track.
+
+Philosophy
+~~~~~~~~~~
+
+Zen of Python
+=============
+
+Try it out at the shell::
+
+    import this
+
+My favorite parts:
+
+* Explicit is better than implicit.
+* Simple is better than complex.
+* Readability counts.
+* Errors should never pass silently.
+
+PEP-8 is my friend
+==================
+
+No `import *`! Even in `urls.py`!
+
+All Docs go on rtfd.org!
+========================
+
+No alternative compares to http://rtfd.org. Not github, bitbucket, or google project wikis compare. And even the python.packages.com site is out of the lead of rtfd.org. Stop trying other things and come to the current leader in documentation hosting. Why?
+
+1. It takes your repo and makes it look awesome.
+2. It puts all the Python docs into one place for good searching.
+3. It plays nice with git, hg, and svn. Wikis generally are through the web.
+4. You can accept pull requests on docs. This way you can edit/reject bad documentation.
+6. Makes your project and work much more visible.
+7. The lead maintainer, Eric Holscher, is incredibly supportive and has both PSF and Revsys support. 
+
+Code Bits
+~~~~~~~~~~
+
+Docs
+====
+
+Besides `admin.py`, all new python files need to be added to the appropriate `app_<app_name>.rst` or `reference_<app_name>.rst` file.
+
+Templates
+=========
+
+* `snippets/_<name>.html` is for templates that are added via `include` or `templatetags`.
+* ``{# unstyled #}`` is a flag for designers that the template is still untouched by their hands.
+
+urls.py
+=======
+
+Even in urls.py you want clean code, right?
+
+Explicit imports
+----------------
+
+See how it is done::
+
+    # See this commented out? 'import *' usually slows things down AND makes it harder to debug
+    # import *
+
+    # Explicit imports are easier to debug
+    from polls import views
+    ...
+
+Using the url() function
+------------------------
+
+Pythonistas love explicitly but this is implicit and henceforth not ideal::
+
+    # Don't do this!
+    url(
+        r'^$',
+        views.poll_list,
+        'poll_list',
+    ),
+    
+    # Or this!
+    (
+        r'^$',
+        views.poll_list,
+        'poll_list',
+    ),
+
+And here is the preferred and wonderfully explicit Jacob Kaplan-Moss / Frank Wiles pattern::
+
+    url(
+        regex=r'^$',
+        view=views.poll_list,
+        name='poll_list',
+    ),
+
+See how each argument is explicitly named? Wonderful!
+    
+
+Calling specific views
+----------------------
+
+This is hard to debug because Django gets a bit too 'magical' and the trace often doesn't give you as much or is longer::
+
+    # Don't do this!
+    url(
+        regex=r'^$',
+        view='polls.views.standard.poll_list', # this single bit makes it harder to debug on errors
+        name='poll_list',
+    ),
+
+Instead we do this::
+
+    url(regex=r'^$',
+        view=views.poll_list,
+        name='poll_list',
+    ),
+    
+Generic Exceptions are the DEVIL
+---------------------------------
+
+This is the DEVIL::
+
+    try:
+        do_blah()
+    except:
+        pass
+        
+Do this instead::
+
+    class BlahDoesNotWork(Exception): pass
+
+    try:
+        do_blah
+    except ImportError:
+        # do something
+    except AttributeError:
+        # do something else
+    except Exception as e:
+        msg = "{0} has failed!".format(str(e))
+        logging.error(msg)
+        raise BlahDoesNotWork(msg)

docs/from_designer_to_djangoer.rst

+From Designer to Django'er in Six Weeks
+=======================================
+
+1. Start out on the right foot:
+    * If you can, spend 100% of your time on your project.
+    * Have a large savings account, low debt.
+    * Make sure you're having fun.
+    * Success can be just launching the app.
+    * Be focused and optimistic before you start.
+
+Cofounders are awesome, but no cofounder is better than the wrong cofounder.
+
+2. Launch as fast as possible:
+    * What can you take out?
+    * Launch tiny bits to keep motivated.
+    * Work on the hard stuff first.
+    * Spent as little time as possible on learning, as much on building.
+    * Launch with bad code (really, it's okay).
+
+3. Have a plan for monetization
+
+4. Don't be forever alone:
+    * Talk to friends.
+    * Don't be prideful; accept help.
+    * NDAs suck.
+    * Surround yourself with good people & resources.
+
+5: Take shortcuts:
+    * Django is plug & play
+    * South, django-registration, django-profiles, sorl-thumbnail, django-debug-toolbar, djangopackages
+    * dotCloud
+    * virtualenv, pip
+
+5.5 Design shortcuts:
+    * themeforest
+    * 99designs (quick logos only)
+    * "The Non-designer's Design Book"
+    * Create a coming-soon page.
+
+Q&A
+===
+
+1. Django/Python rough edges?
+    * Review logic first (when learning).
+    * Had lots of people to ask questions to. Removed most (all?) speed bumps.
+
+2. Why choose Django and stay with it?
+    * Chose Python, really, not just Django.
+    * Django provides for lazy developing :)
+
+3. How did you find customers?
+    * Cold emailing for the vendors.
+    * Blogs and promotion help a lot.
+
+4. How to rein in a designer that likes to design hard-to-build items?
+    * Make him build it!
+    * Pluggables never exactly match.
+
+5. How far did your roadmap go?
+    * Not far at all.
+
+
+.. sphinxified-django documentation master file, created by
+   sphinx-quickstart on Tue Jun 21 12:25:32 2011.
+   You can adapt this file completely to your liking, but it should at least
+   contain the root `toctree` directive.
+
+Why django-party-pack?
+=======================
+
+Because these are great patterns and tools that beginners should be exposed to right away. I've learned them from the various :ref:`contributors`, who are people I admire as Django and Python developers.
+
+Basic Stuff
+-----------
+
+.. toctree::
+   :maxdepth: 2
+   
+   install
+   setup_testrunner
+   javascript
+   conventions
+   contributors
+   
+API/Reference Docs
+--------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   reference_polls
+   
+
+Indices and tables
+==================
+
+* :ref:`genindex`
+* :ref:`modindex`
+* :ref:`search`
+
+.. _`Sphinx`: http://pypi.python.org/pypi/Sphinx
+=============
+Installation
+=============
+
+.. note:: For things with the following it means type it at the command line and hit enter::
+
+    $ ls -al
+
+Before you start
+================
+
+Do you have pip, virtualenv, virtualenvwrapper, and git-scm installed? If not, you'll need to get those on your machine before proceeding.
+
+If you need to install pip::
+
+    $ curl -O https://raw.github.com/pypa/pip/master/contrib/get-pip.py
+    $ python get-pip.py
+    
+If you need to install virtualenv::
+
+    $ pip install virtualenv
+    
+If you need to install virtualenvwrapper::
+
+    $ pip install virtualenvwrapper
+
+If you need to install git:
+
+    * http://git-scm.com
+
+The Basics
+===========
+
+Create a virtualenv for this project. We do this so we isolate all our work from the rest of Python on our computer::
+
+    $ mkvirtualenv dpkenv
+
+Now we clone django-party-pack and go into django-party-pack::
+
+    $ git clone https://pydanny@github.com/pydanny/django-party-pack.git
+    $ cd django-party-pack
+    
+Now let's install our dependencies::
+
+    $ pip install -r requirements.txt
+    
+This may take a few minutes. Feel free to go get some coffee. :)
+
+Settings setup
+===============
+
+We're going to follow what Django BDFL Jacob Kaplan-Moss `advocates as best practices for dealing with settings`_. That means we're going to ignore the manage.py file in the root of our Django project and use the django-admin.py script. In order to do that, we need to take a few more steps.
+
+First, we add some virtualenv bits to allow us to access the settings properly::
+
+    $ echo "export DJANGO_SETTINGS_MODULE=settings.local" >> $VIRTUAL_ENV/bin/postactivate
+    $ echo "unset DJANGO_SETTINGS_MODULE" >> $VIRTUAL_ENV/bin/postdeactivate
+    
+This will allow you to eschew passing in --settings= into management commands.
+
+Now we add to the virtualenv paths our pollaxe project::
+
+    add2virtualenv <<path to django-party-pack repo>>/pollaxe
+
+Running standard Django Commands
+================================
+
+Try out the project::
+
+    $ django-admin.py syncdb
+    $ django-admin.py runserver
+
+Running django-coverage
+========================
+
+Simple run this command::
+
+    $ django-admin.py test
+
+Now open the pollaxe/coverage/index.html file in your favorite browser.
+
+    
+Building these sphinx docs
+==========================
+
+Want to have a local copy of these documents? Easy! Change to our docs directory::
+
+    $ cd docs
+
+Now we generate the sphinx docs in html format::
+
+    $ make html
+
+.. _`advocates as best practices for dealing with settings`: http://www.slideshare.net/jacobian/the-best-and-worst-of-django/51

docs/javascript.rst

+==========
+JavaScript
+==========
+
+Some ideas to incorporate JavaScript into your application.
+
+Coding Standard for JavaScript
+===============================
+
+ * https://github.com/jbalogh/zamboni/blob/master/STYLE.rst
+@ECHO OFF
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+	set SPHINXBUILD=sphinx-build
+)
+set BUILDDIR=_build
+set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% .
+if NOT "%PAPER%" == "" (
+	set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS%
+)
+
+if "%1" == "" goto help
+
+if "%1" == "help" (
+	:help
+	echo.Please use `make ^<target^>` where ^<target^> is one of
+	echo.  html       to make standalone HTML files
+	echo.  dirhtml    to make HTML files named index.html in directories
+	echo.  singlehtml to make a single large HTML file
+	echo.  pickle     to make pickle files
+	echo.  json       to make JSON files
+	echo.  htmlhelp   to make HTML files and a HTML help project
+	echo.  qthelp     to make HTML files and a qthelp project
+	echo.  devhelp    to make HTML files and a Devhelp project
+	echo.  epub       to make an epub
+	echo.  latex      to make LaTeX files, you can set PAPER=a4 or PAPER=letter
+	echo.  text       to make text files
+	echo.  man        to make manual pages
+	echo.  changes    to make an overview over all changed/added/deprecated items
+	echo.  linkcheck  to check all external links for integrity
+	echo.  doctest    to run all doctests embedded in the documentation if enabled
+	goto end
+)
+
+if "%1" == "clean" (
+	for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i
+	del /q /s %BUILDDIR%\*
+	goto end
+)
+
+if "%1" == "html" (
+	%SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/html.
+	goto end
+)
+
+if "%1" == "dirhtml" (
+	%SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml.
+	goto end
+)
+
+if "%1" == "singlehtml" (
+	%SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml
+	echo.
+	echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml.
+	goto end
+)
+
+if "%1" == "pickle" (
+	%SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle
+	echo.
+	echo.Build finished; now you can process the pickle files.
+	goto end
+)
+
+if "%1" == "json" (
+	%SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json
+	echo.
+	echo.Build finished; now you can process the JSON files.
+	goto end
+)
+
+if "%1" == "htmlhelp" (
+	%SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp
+	echo.
+	echo.Build finished; now you can run HTML Help Workshop with the ^
+.hhp project file in %BUILDDIR%/htmlhelp.
+	goto end
+)
+
+if "%1" == "qthelp" (
+	%SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp
+	echo.
+	echo.Build finished; now you can run "qcollectiongenerator" with the ^
+.qhcp project file in %BUILDDIR%/qthelp, like this:
+	echo.^> qcollectiongenerator %BUILDDIR%\qthelp\django-party-pack.qhcp
+	echo.To view the help file:
+	echo.^> assistant -collectionFile %BUILDDIR%\qthelp\django-party-pack.ghc
+	goto end
+)
+
+if "%1" == "devhelp" (
+	%SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp
+	echo.
+	echo.Build finished.
+	goto end
+)
+
+if "%1" == "epub" (
+	%SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub
+	echo.
+	echo.Build finished. The epub file is in %BUILDDIR%/epub.
+	goto end
+)
+
+if "%1" == "latex" (
+	%SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex
+	echo.
+	echo.Build finished; the LaTeX files are in %BUILDDIR%/latex.
+	goto end
+)
+
+if "%1" == "text" (
+	%SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text
+	echo.
+	echo.Build finished. The text files are in %BUILDDIR%/text.
+	goto end
+)
+
+if "%1" == "man" (
+	%SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man
+	echo.
+	echo.Build finished. The manual pages are in %BUILDDIR%/man.
+	goto end
+)
+
+if "%1" == "changes" (
+	%SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes
+	echo.
+	echo.The overview file is in %BUILDDIR%/changes.
+	goto end
+)
+
+if "%1" == "linkcheck" (
+	%SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck
+	echo.
+	echo.Link check complete; look for any errors in the above output ^
+or in %BUILDDIR%/linkcheck/output.txt.
+	goto end
+)
+
+if "%1" == "doctest" (
+	%SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest
+	echo.
+	echo.Testing of doctests in the sources finished, look at the ^
+results in %BUILDDIR%/doctest/output.txt.
+	goto end
+)
+
+:end

docs/reference_polls.rst

+========================
+Reference for Polls App
+========================
+
+The polls app is a copy of the Django tutorial with some mild PEP-8 cleanup.
+
+``polls.models``
+=================
+.. automodule:: polls.models
+    :members:
+    
+``polls.views``
+=================
+.. automodule:: polls.views
+    :members:
+
+``polls.tests``
+=================
+.. automodule:: polls.tests.test_models
+    :members:
+    :undoc-members:
+    
+.. automodule:: polls.tests.test_views
+    :members:
+    :undoc-members:    

docs/requirements.txt

+django==1.3
+sphinx==1.0.7
+django-coverage==1.2.1
+coverage==3.4

docs/setup_testrunner.rst

+=========================
+Setting up a test runner
+=========================
+
+Ned Batchelder's coverage.py is an invaluable tool for any Python project. django_coverage makes coverage.py run inside of Django, and this is my preferred way of using that tool.
+
+Step 1 - environment prep
+=========================
+
+In your requirements.txt file, make sure you have the following::
+
+    django-coverage==1.2
+    coverage==3.4
+
+In your virtualenv install the necessary requirements::
+
+    $ pip install -r requirements.txt
+
+Make a `coverage` directory in your project directory::
+
+    # This is done for you in django-party-pack
+    #   but you'll need to remember it for future projects
+    $ mkdir coverage
+
+Step 2 - create testrunner.py
+=============================
+
+Create a testrunner.py file into your project root and paste in the following code::
+
+    # Make our own testrunner that by default only tests our own apps
+
+    from django.conf import settings
+    from django.test.simple import DjangoTestSuiteRunner
+    from django_coverage.coverage_runner import CoverageRunner
+
+    class OurTestRunner(DjangoTestSuiteRunner):
+        def build_suite(self, test_labels, *args, **kwargs):
+            return super(OurTestRunner, self).build_suite(test_labels or settings.PROJECT_APPS, *args, **kwargs)
+
+    class OurCoverageRunner(OurTestRunner, CoverageRunner):
+        pass
+
+Step 3 - settings customization
+===============================
+
+The first thing you'll notice about dpp is that apps installment is broken up into three variables:
+
+ * `PREREQ_APPS` - These are either built-in Django apps or third-party apps you don't want to test.
+ * `PROJECT_APPS` - These are the custom apps you've written for your project. You want to test these.
+ * `INSTALLED_APPS` - This is what Django loads into it's app cache. We generate this iterable by adding `PREREQ_APPS` to `PROJECT_APPS`.
+ 
+Here is the sample code from dpp/pollaxe project settings.py file::
+ 
+    PREREQ_APPS = (
+         'django.contrib.auth',
+         'django.contrib.contenttypes',
+         'django.contrib.sessions',
+         'django.contrib.sites',
+         'django.contrib.messages',
+         'django.contrib.admin',
+    )
+
+    PROJECT_APPS = (
+        'polls', # or whatever your custom project uses
+    )
+
+    INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS 
+
+Also in settings.py, underneath where you have defined the `PREREQ_APPS` setting, add the following::
+
+    TEST_RUNNER = 'testrunner.OurCoverageRunner'
+    COVERAGE_MODULE_EXCLUDES = [
+        'tests$', 'settings$', 'urls$', 'locale$',
+        'migrations', 'fixtures', 'admin$',
+    ]
+    COVERAGE_MODULE_EXCLUDES += PREREQ_APPS
+    COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage"
+
+Step 4 - run it!
+================
+
+From the command-line::
+
+    $ python manage.py test
+
+Open file:///path-to-your-project/coverage/index.html in a web browser and check out your coverage.

docs/the_story_and_tech_of_read_the_docs.rst

+The Story and Tech of Read The Docs
+===================================
+
+

pollaxe/__init__.py

+# -*- coding: utf-8 -*-
+"""
+See PEP 386 (http://www.python.org/dev/peps/pep-0386/)
+
+Release logic:
+1. Remove the "dev" part from current, save file.
+2. git commit
+3. git tag <version>
+4. push to pypi + push to github
+5. bump the version, append '.dev0'
+6. git commit
+7. push to github (to avoid confusion)
+"""
+__version__ = '0.0.0.dev0'
+

pollaxe/manage.py

+#!/usr/bin/env python
+from django.core.management import execute_manager
+try:
+    import settings # Assumed to be in the same directory.
+except ImportError:
+    import sys
+    sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
+    sys.exit(1)
+
+if __name__ == "__main__":
+    execute_manager(settings)

pollaxe/polls/__init__.py

Empty file added.

pollaxe/polls/admin.py

+import datetime
+
+from django.contrib import admin
+
+from polls.models import Poll, Choice
+
+
+class PollAdmin(admin.ModelAdmin):
+        fieldsets = [
+            (None,               {'fields': ['question']}),
+            ('Date information', {'fields': ['pub_date']}),
+        ]
+
+class ChoiceInline(admin.StackedInline):
+    model = Choice
+    extra = 3
+
+class PollAdmin(admin.ModelAdmin):
+    fieldsets = [
+        (None,               {'fields': ['question']}),
+        ('Date information', {'fields': ['pub_date'], 'classes': ['collapse']}),
+    ]
+    inlines = [ChoiceInline]
+    list_display = ('question', 'pub_date',)# 'was_published_today')
+    
+    #def was_published_today(self):
+    #    return self.pub_date.date() == datetime.date.today()
+        
+    #was_published_today.short_description = 'Published today?'    
+
+admin.site.register(Poll, PollAdmin)

pollaxe/polls/models.py

+import datetime 
+from django.db import models
+
+class Poll(models.Model):
+    """An individual poll to be tested"""
+    question = models.CharField(max_length=200)
+    pub_date = models.DateTimeField('date published')
+    
+    def __unicode__(self):
+        return self.question
+    
+    def was_published_today(self):
+        return self.pub_date.date() == datetime.date.today()
+
+class Choice(models.Model):
+    """Choices on a poll"""
+    poll = models.ForeignKey(Poll)
+    choice = models.CharField(max_length=200)
+    votes = models.IntegerField()
+    
+    def __unicode__(self):
+        return self.choice    

pollaxe/polls/tests/__init__.py

+from polls.tests.test_models import *
+from polls.tests.test_views import *

pollaxe/polls/tests/test_models.py

+from datetime import datetime, timedelta
+
+from django.contrib.auth.models import User
+from django.test import TestCase
+
+from polls.models import Choice, Poll
+from polls.tests.utils import BaseTestCase
+
+class TestPolls(BaseTestCase):
+    
+    
+    def test_poll_create(self):
+        """ Can we create a poll?
+        
+        * Seems trivial now
+        * But for complex systems what started out as a simple create can get complex
+        * Get your test coverage up!
+        """                
+        
+        poll_count = Poll.objects.count()
+        poll = Poll(
+            question="Why is Python awesome?",
+            pub_date=datetime.now()
+        )
+        poll.save()
+        self.assertTrue(poll_count < Poll.objects.count())
+        
+    def test_was_published_today(self):
+        
+        poll = Poll(
+            question="Django is for the internets",
+            pub_date=datetime.now()
+        )
+        poll.save()
+        self.assertTrue(poll.was_published_today())
+        
+        poll.pub_date = datetime.now() - timedelta(days=3)
+        poll.save()
+        
+        self.assertFalse(poll.was_published_today())

pollaxe/polls/tests/test_views.py

+from datetime import datetime, timedelta
+
+from django.core.urlresolvers import reverse
+from django.contrib.auth.models import User
+from django.test import TestCase
+
+from polls.models import Choice, Poll
+from polls.tests.utils import BaseTestCase
+
+class TestPollSample(BaseTestCase):
+    
+    def setUp(self):
+        super(TestPollSample,self).setUp()
+        self.poll = Poll(
+            question="What is your favorite number?",
+            pub_date=datetime.now()
+        )
+        self.poll.save()
+        for i in range(1, 4):
+            choice = Choice(
+                poll = self.poll,
+                choice=str(i),
+                votes=0
+            )
+            choice.save()        
+    
+    
+    def test_poll_index(self):
+        """ Check if the poll index displays """        
+        
+        # Now display me a poll!
+        url = reverse("poll_index")
+        response = self.client.get(url)
+        
+        # Show them the print!
+        #print response
+        
+        self.assertContains(response, "What is your favorite number?")
+        
+    def test_poll_detail(self):
+        """ Check if the poll detail displays """
+        
+        # Grab poll again to make sure we get right ID and that
+        #   any custom save methods have been fully fired
+        poll = Poll.objects.get(id=self.poll.id)
+        
+        url = reverse("poll_detail", kwargs={"poll_id": poll.id})
+        response = self.client.get(url)
+        
+        self.assertContains(response, "What is your favorite number?")        
+        
+    def test_poll_vote(self):
+        """ vote on a poll """
+        url = reverse("poll_vote", kwargs={"poll_id": self.poll.id})
+        
+        # Pick a bad choice out of range
+        data = dict(choice = 10)
+        response = self.client.post(url, data, follow=True)
+        self.assertContains(response, "You didn&#39;t select a choice.")
+        
+        # pick a choice in range
+        data = dict(choice = 2)
+        response = self.client.post(url, data, follow=True)
+        self.assertContains(response, "<li>2 -- 1 vote</li>")
+        

pollaxe/polls/tests/utils.py

+from django.contrib.auth.models import User
+from django.test import TestCase
+      
+
+class BaseTestCase(TestCase):
+    
+    urls = 'polls.urls'    
+    
+    def setUp(self):
+        """ Provides a self.user and self.user_pw
+        
+        usage::
+
+            from polls.tests.utils import BaseTestCase
+            class MyTest(BaseTestCase):
+
+                def setUp(self):
+                    super(MyTest,self).setUp()                
+                    # stick in custom setUp bits here
+                    # stick in custom setUp bits here
+                    # stick in custom setUp bits here                                
+                """
+
+        # I always forget the password
+        self.user_pw = 'test'
+
+        # Create a sample user
+        self.user = User.objects.create_user('pydanny','pydanny@test.com',self.user_pw,)
+        self.user.first_name = "Danny"
+        self.user.last_name = "Greenfeld"
+        self.user.save()
+        
+    def tearDown(self):
+        self.client.logout()
+        
+    def login(self, user, password):
+        return login(self, user, password)

pollaxe/polls/urls.py

+from django.conf.urls.defaults import patterns, url
+
+from polls import views
+
+urlpatterns = patterns('',
+
+    url(
+        regex=r'^$',
+        view=views.index,
+        name='poll_index',
+    ),
+
+    url(
+        regex=r'^(?P<poll_id>\d+)/$',
+        view=views.detail,
+        name='poll_detail',
+    ),
+    
+    url(
+        regex=r'(?P<poll_id>\d+)/results/$',
+        view=views.results,
+        name='poll_results'
+    ),
+    
+    url(
+        regex=r'(?P<poll_id>\d+)/vote/$',
+        view=views.vote,
+        name='poll_vote'
+    ),
+    
+    # DON'T DO THIS!!!
+    # This is a tuple and hence takes moar smartz to read
+    # I call this 'baby obfuscated code'
+    #(r'^blarg/$', views.poll_detail, "poll_detail")
+    
+    # DON'T DO THIS!!!
+    # This is less explicit view call and Django has to do 'magic' to make it work
+    # This means your stacktrace for generated bugs is longer
+    # I call this 'making your code harder to debug'
+    #url(
+    #    regex=r'^(?P<poll_id>\d+)/$',
+    #    view="polls.views.poll_detail",
+    #    name='poll_detail',
+    #),
+    
+)
+

pollaxe/polls/views.py

+from django.core.urlresolvers import reverse
+from django.http import HttpResponse, HttpResponseRedirect
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template import Context, loader, RequestContext
+
+from polls.models import Poll, Choice
+
+POLL_DETAIL_TEMPLATE = "polls/detail.html"
+
+# We pass the template_name as a variable because it makes the template function easier to 
+# identify AND because it means it can be changed on the fly
+def index(request, template_name="polls/index.html"):
+    """ Show a list of polls"""
+    latest_poll_list = Poll.objects.all().order_by('-pub_date')[:5]
+    return render_to_response(template_name, {'latest_poll_list': latest_poll_list})
+
+
+def detail(request, poll_id, template_name=POLL_DETAIL_TEMPLATE):
+    """ Show detail on a poll"""    
+    
+    # I used 'poll' instead of 'p' because the pixel shortage is over.
+    # If this is too much typing, then just cut-and-paste, okay?
+    poll = get_object_or_404(Poll, pk=poll_id)
+    choices = Choice.objects.filter(poll=poll)
+    return render_to_response(template_name, {
+        'poll': poll,
+        'choices': choices }, 
+        context_instance=RequestContext(request))    
+
+def vote(request, poll_id, template_name=POLL_DETAIL_TEMPLATE):
+    """ user votes on a poll"""
+
+    poll = get_object_or_404(Poll, pk=poll_id)
+    try:
+        selected_choice = poll.choice_set.get(pk=request.POST['choice'])
+    except (KeyError, Choice.DoesNotExist):
+        # Redisplay the poll voting form.
+        return render_to_response(template_name, {
+            'poll': poll,
+            'error_message': "You didn't select a choice.",
+        }, context_instance=RequestContext(request))
+    else:
+        selected_choice.votes += 1
+        selected_choice.save()
+        # Always return an HttpResponseRedirect after successfully dealing
+        # with POST data. This prevents data from being posted twice if a
+        # user hits the Back button.
+        url = reverse('poll_results', args=(poll.id,))
+        return HttpResponseRedirect(url)
+        
+def results(request, poll_id, template_name="polls/results.html"):
+    poll = get_object_or_404(Poll, pk=poll_id)
+    return render_to_response(template_name, 
+        {'poll': poll},
+        context_instance=RequestContext(request)
+        )
+        
+        

pollaxe/settings/__init__.py

Empty file added.

pollaxe/settings/base.py

+# Django settings for pollaxe project.
+
+import os
+
+settings_dir = os.path.dirname(__file__)
+PROJECT_ROOT = os.path.abspath(os.path.dirname(settings_dir))
+
+
+DEBUG = True
+TEMPLATE_DEBUG = DEBUG
+
+ADMINS = (
+    #('Your Name', 'your_email@domain.com'),
+)
+
+MANAGERS = ADMINS
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': 'base.db',                      # Or path to database file if using sqlite3.
+        'USER': '',                      # Not used with sqlite3.
+        'PASSWORD': '',                  # Not used with sqlite3.
+        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}
+
+TIME_ZONE = 'America/Chicago'
+
+LANGUAGE_CODE = 'en-us'
+
+SITE_ID = 1
+
+USE_I18N = True
+
+USE_L10N = True
+
+MEDIA_URL = '/media/'
+MEDIA_ROOT = os.path.realpath(os.path.join(PROJECT_ROOT, "media"))
+
+STATIC_URL = '/static/'
+STATIC_ROOT = os.path.realpath(os.path.join(PROJECT_ROOT, "static"))
+
+ADMIN_MEDIA_PREFIX = '/media/'
+
+# Make this unique, and don't share it with anybody.
+SECRET_KEY = '<make-me-unique>'
+
+# List of callables that know how to import templates from various sources.
+TEMPLATE_LOADERS = (
+    'django.template.loaders.filesystem.Loader',
+    'django.template.loaders.app_directories.Loader',
+)
+
+MIDDLEWARE_CLASSES = (
+    'django.middleware.common.CommonMiddleware',
+    'django.contrib.sessions.middleware.SessionMiddleware',
+    'django.middleware.csrf.CsrfViewMiddleware',
+    'django.contrib.auth.middleware.AuthenticationMiddleware',
+    'django.contrib.messages.middleware.MessageMiddleware',
+)
+
+ROOT_URLCONF = 'pollaxe.urls'
+
+TEMPLATE_DIRS = (
+    os.path.join(PROJECT_ROOT, "templates"),
+)
+
+PREREQ_APPS = (
+    'django.contrib.auth',
+    'django.contrib.contenttypes',
+    'django.contrib.sessions',
+    'django.contrib.sites',
+    'django.contrib.messages',
+    'django.contrib.admin',
+)
+
+PROJECT_APPS = (
+    'polls',
+)
+
+INSTALLED_APPS = PREREQ_APPS + PROJECT_APPS
+
+TEST_RUNNER = 'testrunner.OurCoverageRunner'
+
+COVERAGE_MODULE_EXCLUDES = [
+    'tests$', 'settings$', 'urls$', 'locale$',
+    'migrations', 'fixtures', 'admin$',
+]
+COVERAGE_MODULE_EXCLUDES += PREREQ_APPS
+COVERAGE_REPORT_HTML_OUTPUT_DIR = "coverage"
+
+HTML_OUTPUT_DIR = os.path.join(PROJECT_ROOT, "coverage")
+
+LOGGING = {
+    'version': 1,
+    'disable_existing_loggers': False,
+    'handlers': {
+        'mail_admins': {
+            'level': 'ERROR',
+            'class': 'django.utils.log.AdminEmailHandler',
+        }
+    },
+    'loggers': {
+        'django.request': {
+            'handlers': ['mail_admins'],
+            'level': 'ERROR',
+            'propagate': True,
+        },
+    },
+}
+

pollaxe/settings/dev.py

+from base import *
+
+DATABASES = {
+    'default': {
+        'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
+        'NAME': 'overload.db',          # Or path to database file if using sqlite3.
+        'USER': '',                      # Not used with sqlite3.
+        'PASSWORD': '',                  # Not used with sqlite3.
+        'HOST': '',                      # Set to empty string for localhost. Not used with sqlite3.
+        'PORT': '',                      # Set to empty string for default. Not used with sqlite3.
+    }
+}

pollaxe/templates/polls/detail.html

+<h1>{{ poll.question }}</h1>
+
+{% if error_message %}<p><strong>{{ error_message }}</strong></p>{% endif %}
+
+<form action="{% url poll_vote poll.pk %}" method="post">
+{% csrf_token %}
+{% for choice in poll.choice_set.all %}
+    <input type="radio" name="choice" id="choice{{ forloop.counter }}" value="{{ choice.id }}" />
+    <label for="choice{{ forloop.counter }}">{{ choice.choice }}</label><br />
+{% endfor %}
+<input type="submit" value="Vote" />
+</form>

pollaxe/templates/polls/index.html

+<h1>Show me polls</h1>
+
+{% if latest_poll_list %}
+    <ul>
+    {% for poll in latest_poll_list %}
+        <li><a href="{% url poll_detail poll.pk %}">{{ poll.question }}</a></li>
+    {% endfor %}
+    </ul>
+{% else %}
+    <p>No polls are available.</p>
+{% endif %}

pollaxe/templates/polls/results.html

+<h1>{{ poll.question }}</h1>
+
+<ul>
+{% for choice in poll.choice_set.all %}
+    <li>{{ choice.choice }} -- {{ choice.votes }} vote{{ choice.votes|pluralize }}</li>
+{% endfor %}
+</ul>
+
+<a href="{% url poll_detail poll.pk %}">Vote again?</a>

pollaxe/testrunner.py

+# Make our own testrunner that by default only tests our own apps
+
+from django.conf import settings
+from django.test.simple import DjangoTestSuiteRunner
+from django_coverage.coverage_runner import CoverageRunner
+
+# TODO write something that generates a coverage folder if it doesn't already exist
+
+class OurTestRunner(DjangoTestSuiteRunner):
+    def build_suite(self, test_labels, *args, **kwargs):
+        return super(OurTestRunner, self).build_suite(test_labels or settings.PROJECT_APPS, *args, **kwargs)
+
+class OurCoverageRunner(OurTestRunner, CoverageRunner):
+    pass
+from django.conf.urls.defaults import *
+
+
+from django.contrib import admin
+admin.autodiscover()
+
+urlpatterns = patterns('',
+
+    (r'^admin/', include(admin.site.urls)),
+    (r'^', include("polls.urls")),    
+    
+)

pydanny-django-party-pack-a8bfeb7/.gitignore

+*pyc
+coverage
+_build
+_static
+_templates
+# -*- coding: utf-8 -*-
+from setuptools import setup, find_packages
+import os
+import codecs
+
+# The following classifiers are a good start, and a safe bet
+# A list of classifiers can be found here:
+# http://pypi.python.org/pypi?%3Aaction=list_classifiers
+CLASSIFIERS = [
+     'Development Status :: 2 - Pre-Alpha', # Change this accordingly
+     'Environment :: Web Environment',
+     'Framework :: Django',
+     'Intended Audience :: Developers',
+     'License :: OSI Approved :: BSD License',
+     'Operating System :: OS Independent',
+     'Programming Language :: Python',
+     'Programming Language :: Python :: 2',
+     'Programming Language :: Python :: 2.6', # Maybe add 2.7
+]
+
+setup(
+    author="#YOUR NAME HERE#",
+    author_email="#YOU EMAIL HERE#",
+    name='django-party-pack',
+    
+    # The actual version string is defined in pollaxe/__init__.py
+    version= __import__('pollaxe').__version__
+    
+    description='A Party pack for django!',
+
+    # The following line uses README.rst as long description.
+    long_description=codecs.open(os.path.join(os.path.dirname(__file__), 'README.rst'), 'utf-8').read(),
+
+    # Tip: do NOT use download-url! This makes it really painful for most
+    # people using tools like buildout. Simply host your downloads on pypi, and
+    # stop worrying.
+
+    url='#A website URL here#',
+    
+    license='BSD License', # Obviously change it to something relevant
+    platforms=['OS Independent'], # Python! Yay!
+    
+    classifiers=CLASSIFIERS,
+
+    # This might seem like a repetition of requirements.txt, but this applies
+    # to the *package*, and requirements are for the *environment*.
+    install_requires=[
+        'django==1.3',
+        'sphinx=1.0.7',
+        'django-coverage==1.2.1',
+        'coverage==3.4',
+    ],
+
+    packages=find_packages(), #This auto-finds and includes python pacakges!
+    include_package_data=True,
+    zip_safe = False,
+)
+