Bump package requirements
Remove deprecated verify_exists URLField param
Add ipython as req, use venv python for manage.py

(instead of /usr/bin/env python)
Remove workaround for _collect_sub_objects bug

Fixed in Django 1.5
Quote first parameter to {% url %} template tag
Replace deprecated reversion.revision.create_on_success
Replace deprecated generic views in url; delete unused ones URLs
Reorder imports (& remove unused)
Clean up imports
Add cssselect package to requirements

It was taken out of the main lxml package
Update to Django 1.5.1
Tweak username creation algorithm & add test
Remove "import *" from main/tests.py
Split up models.py into a module

As a result, needed to add some imports to admin.py.
Try again at NoteSection model

In b8cac7a I got rid of note sections in favor of just using citations.
At the time, I said that if we wanted to go back to note sections, "we
can make [different types of sections] into their own models, and have
note sections be a generic foreign key to them". That's what this commit
does, except using concrete inheritence instead of generic
relationships.

The three types of note sections I've included:
	* Citations
	* Text
	* references to other notes

These distinct sections are all stored in different tables, but in most
cases, we will want to retrieve them by getting all of a notes'
sections, regardless of their subclasses. To accomplish this without
hitting the database much, I've added django-model-utils as a
requirement. It includes a manager for such a use case. See the article
"Automatic Downcasting of Inherited Models in Django" [1] for the basis
of this manager.

An advantage of this split is that we will be able to add different
types of sections in a modular way. Next I'll need to make serializers
and templates for each type of new section.

[1] http://jeffelmore.org/2010/11/11/automatic-downcasting-of-inherited-models-in-django/
Migrate data over for Citation note sections

Changes citations with a generic relation to a note -> Citation note
sections
Update note section imports in forms

This is broken, but it will stop raising an Exception
New "distributed" topic model(s)

Topics are now recast as "topic nodes" that contain connections to
projects. For now, those connections are names, summaries, and topic
assignments. In the future it's easy to imagine structured data will
fall in the same category.

Also added fixtures for basic multi-project & user setup. The tests for
the new topics rely on these fixtures.
Migrate data to distributed topic models

Migration 0089 is a beast. I'm truly, truly sorry. OK, to it now--

In 20fef76 I introduced several new models (TopicSummary, TopicName,
TopicNode) to replace the Topic model, in order to make "topics" (the
concept) more modular and more fitted to having multiple projects work
on them. This commit migrates data over to the new topic models and
begins adapting everything else to work with them. I will first describe
the four migrations and then summarize what has been changed in the
architecture of the site.

A few of these commits take a really long time to run on our existing
database, so I'm going to include a soundtrack to go with each of them.

* (0088) John Cale - "Guts"
All TopicCluster objects from the `refine` module deleted. This is no
longer how we will deal with "merging" topics that refer to the same
thing. See 20fef76, especially the new methods introduced in the
TopicNode model to see the new methods of merging "pointers" to a topic
rather than topics themselves.

* (0089) Killing Joke - "Unspeakable" (repeat 10x very, very loud)
It's actually embarrassing how much time this commit stole from my
life-- chiefly because there were so many complicated DB transactions
involved that *had* to go through django's ORM. Basically what this
migration does is make new TopicNode, TopicName, TopicSummary,
TopicNodeAssignment, and Version (from reversion) objects based on the
previously existing Topic models. These new objects were most often
based on old Version/Revision data. I made some pretty simple heuristics
to determine ownership by project, but there are definitely (relatively
few, I hope) stragglers which will need to be manually edited. As with
previous data migrations (e.g. 0085 converting citations -> note
sections), this migration had the unintended consequence of forcing me
to clean up some of our old reversion data.

* (0090) Faure - Impromptu no. 2 in F minor, op. 31
Delete old topic models (Alias, TopicAssignment), as well as most of the
Topic model (but not the model itself.. see 91)

* (0091) The Beach Boys - "Please Let Me Wonder"
Add a new field (merged_into) to the Topic model, so that topic objects
point to the TopicNode that they were folded into in 0089. We may
decide to delete these altogether-- I haven't decided. For now, the old
topic URLs give a 301 redirect to their respective TopicNode pages.

So now, for the rest of it-- I temporarily disabled all of the apps in
our projects outside of 'main', because they all need to be adapted in
turn to the new topic model. That includes the API, custom admin pages,
and refine apps. I'm not sure what will come next-- adapting those as
they are now, or getting the permissions situation under control.
Reimplement project-sepecific permissions

This completely changes (and completely improves) how we handle
project-specific permissions.

1. A new mixin called ProjectPermissionsMixin must be inherited by any
object which should have project-specific permissions. These permissions
are recorded & updated after any database sync operations (syncdb or
migrate). They are just the permissions that django automatically
creates (add, change, delete + any defined custom model perms) for
models that inherit from ProjectPermissionsMixin.

1a. Instead of inheritence, it might be possible/desirable to use the
registration pattern used by, e.g. Django's admin & reversion. That
might go something like `project_permissions.register(model)` somewhere
in models.py

2. I introduced a new model: ProjectRole, which has a name and is
connected (one to one) with a Group which is automatically generated.
That group can contain any of the permissions described in (1) above.
If a project role is defined as a "super role", it will automatically
have all such permissions.

3. Here was the tricky part-- there were several ways that we could have
checked project level permissions. This could have been done in a custom
authentication backend with object-level permissions. That would have
looked something like `user.has_perm('main.change_note', object)`. Since
the ProjectPermissionsMixin allows us to get the "affiliation" of an
object from the required `get_affiliation` method, we could have then
checked if a user had the specific permission in a role in the project.
The reason I didn't like this that much is because it's redundant-- you
have to define the object's app and relevant permission IN ADDITION TO
the object.

The best solution to this would be to be able to say
`user.has_project_perm(project, 'main.change_note')`. This is much
clearer, because we *are* using permissions in a much different way than
django's admin-- we don't want to know if a user has a certain
permission, we want to know if a user has a certain permission in the
context of a certain project.

However, it's not possible to add custom methods to the User model
unless we substitute our own custom User model (which may or not be
beneficial in the future, but would certainly be time-consuming). So,
somewhat disappointingly, I added this method to the UserProfile model.
I like this solution because it makes it *very* explicity how
permissions are checked, so there wouldn't be any slipping up and, for
example, forgetting to pass the object to `has_perm` in the first
solution.

4. There is a new management command `delete_stale_project_perms` which
will remove any permissions that we no longer want to define as project
permissions from any groups which still reference them. This might
happen if we remove a custom permission from a project-specific model,
or if we add to the list of ignored project permissions in
editorsnotes/main/management/__init__.py