Support multiple hive cities in one Django installation

## Problem

Other cities (Chicago, Toronto, Chattanooga, Kansas City, etc) want to have their own Hive Directory.

I originally started this project as a single-city directory, assuming that other Hives could host their own instance, but there's a few wrinkles with this plan:

* Most/all the Hives don't actually have dedicated technical expertise required to deploy and maintain their own instance.
* Through interviews, we've found that there's a significant interest in having functionality that works *across* multiple Hive networks, e.g. making it possible for a Hive Toronto member to discover and connect with an expert in Fashion+Technology in Hive NYC.

One of the advantages of the current Hive Directory app, though, is the fact that it has a **local context**. Many people in Hive NYC, for example, don't usually want or need to connect with people in other cities, and showing them information about Hive networks around the world may be confusing. At the same time, though, there *are* use cases for cities to get up-and-running with their own directory quickly, and for some users to be able to explore the breadth of Hive networks around the world (particularly when their local context doesn't meet their needs).

## Solution

Use Django's [sites framework](https://docs.djangoproject.com/en/dev/ref/contrib/sites/#associating-content-with-multiple-sites) to make it possible for a site to represent either a specific city in its installation *or* the entire Hive ecosystem at large. Because all sites share the same database, changes made on one are automatically reflected in the others.

To illustrate, here's an example of two sites, each powered by the same Django installation:

* **directory.hivenyc.org** offers a local-context, single-city directory for Hive NYC members. Its homepage looks like this:

  <img src="https://cloud.githubusercontent.com/assets/124687/3404900/8ca4c208-fd76-11e3-9c72-8ef5e37cdd5c.png" width="320">

* **directory.hivelearningnetworks.org** offers a global-context, multi-city directory for Hive members around the world, and for cities that don't have the resources to set up their own local-context directory site. Its homepage looks like this:

  <img src="https://cloud.githubusercontent.com/assets/124687/3404905/90aaebc0-fd76-11e3-8b08-2d4d82466a3a.png" width="320">

Clicking on the "New York City" link in the second screen-shot will take the user to a page at `/nyc/` that looks similar (but not *identical*) to the first screen-shot.

## Implementation

The solution requires adding a `City` model to the project and optionally associating it with a `Site` object (for cities like NYC that have their own individual sites). Multi-city, global-context sites are indicated by simply not associating the site with a city object. This can be done on-the-fly through the Django admin interface, without needing to restart the server.

When a site is multi-city, the URL structure changes such that the home page (`/`) is just a list of Hive cities, each of which is linked to a path like `/nyc/` or `/chicago/`, which contains a specific directory scoped to each city. By "directory" we mean organization list view and search functionality; organization detail pages are still hosted at `/orgs/`, users are still at `/users/`, and so forth. Views can subtly alter their display to cater to either the global or local context through various methods on the `City` object, and `site.city` can also be used to obtain information about the current city if the context is local. A new `city_url` template tag can also be used to reverse-map directory-related URLs regardless of the context (e.g., the tag will automatically prepend `/nyc/` to the beginning of the URL if necessary).

## Consequences

There will be a lot more data in the database, so new city-related filters and columns have been added to many admin views to make it possible to easily navigate the database for records pertaining to a specific city.

Other models have been tailored to relate to cities in specific ways:

* The Expertise Exchange (aka "mentoring") app currently works in a global context: that is, if someone looks at the page for experts in Digital Solutions and Possibilities, they will see a list of everyone from all Hive cities that claim this expertise. This interface will be fine-tuned in the future, and individuals will eventually be able to specify whether they want to be reachable by people in other Hive networks.

* Organization membership types are completely specific to particular cities: that is, because different Hives have completely different membership models for organizations, each city must define their membership types differently. A "community" member in Hive Chicago may mean something entirely different from a "community" member in Hive NYC, and individual Hives should have the freedom to define things the way they want.

* The same goes for individual member roles. A "funding liason" in Hive Chicago may not mean anything in a Hive NYC context.

## Edge Cases

* There are a few organizations, like [Iridescent](http://iridescentlearning.org/), that exist in multiple Hive cities. Rather than associating a single organization with multiple cities, though, I think it might actually be better to simply create multiple organizations, e.g. "Iridescent NYC" and "Iridescent Chicago". This allows the information for each to be tailored to their local context. If this turns out to be a bad idea, we can do a schema and data migration.

## Potential Risks

* By putting all Hives into the same database, we're centralizing information in a way that may ultimately provide less flexibility than some Hive networks want or need. It also introduces a single point of failure into the operations of all Hive networks. (That said, there's no reason such organizations can't just host their own separate Django installation of the project and make whatever changes they want.)

* Doing database migrations will require taking *all* directories for all Hive networks offline for a period of time.

* Accidental or intentional deletion of data could spill over from one city into another, e.g. an administrator from Hive Chicago could accidentally delete Hive NYC user data. (This can be alleviated by adding more access controls, but they're currently not implemented, and even that still doesn't address cases involving security vulnerabilities or bugs.)

* The complexity introduced by the notion of a multi-city site and its resultant changes could make it harder and more confusing for newcomers to contribute to this project, and for existing developers (i.e., me) to maintain it.

* Testing becomes harder, as we ideally need to test the project with multi-city and single-city sites to achieve full code coverage. A `using_multi_city_site` decorator has been added to make this easier (by default, tests assume that they're running on a single-city site).

* Design iterations that require schema changes may become harder: if we want to try out an interesting idea on the Hive NYC site that requires a schema change to an existing model, we need to make that schema change on *all* Hive directories, since they share the same database. This could result in social friction (what if some Hives don't like the schema change?). It can potentially be alleviated by modularizing new functionality into separate Django apps, or adding third-party APIs like OAuth to the directory that allow additional functionality to be added requiring only end-user approval.

* Hives exists in non-English speaking countries, so we'll likely need internationalize the app eventually... But at the same time, it would be great to be able to iterate on the directory without having to incorporate string freezes into the development cycle. Perhaps this is just an inevitability regardless.

## Alternatives

Instead of making these changes, we could build APIs that allow completely separate Hive directory instances to communicate with each other when needed. Services like [bitnami](https://bitnami.com/) and tools like [Docker](https://github.com/discourse/discourse/blob/master/docs/INSTALL.md) could also be leveraged to reduce the cost of getting an instance up and running.