Remove many SQL queries from the review request page.

It turns out the review request page had a terribly large number of SQL
queries being performed. This is the first step in removing those and
simplifying the code.
Pass the list of diffsets and public reviews to ReviewRequest.get_last_activity.

ReviewRequest.get_last_activity can now take a list of diffsets and
review to operate on. This works as an optimization when you don't need
that function to perform its own queries. We use this in review_detail
now in order to reduce the number of queries we need to make.
Optimize comment loading.

Instead of loading lists of comments, we now load the through tables
inbetween the comment and review. This allows us to do a select_related
that will fetch the comment and the review at the same time, making it
cheaper to map into the entry with the review ID.
Store the last reply timestamps without doing a query per review.

We had a query per review to get the timestamp of the latest reply. This
wasn't very efficient. Now, we just do the calculations when iterating
over all the reviews.
Set the review request on some objects to prevent further lookups.

Several objects (Comment, ScreenShot, FileAttachment, etc.) performed
queries to get the associated review request, in order to generate URLs.
Where we're using them, though, we already know the review
request. So, short-circuit by setting a special _review_request attribute.
Provide accessor methods for screenshots and file attachments.
Reduce queries for reviews, replies, and comments.

Each reply to a review was generating queries for each comment, each
replied review, and each user. These ballooned up in size quite a bit.

We now cache these along with everything else we're caching to reduce
lookups. The lists of replies are all computed at one place when we're
computing everything else, and new accessors on Review and BaseComment
make it easy to grab the results without assuming a query.
Use user IDs instead of users in the templates for several checks.

There were lots of template tags that were being passed users instead of
just user IDs, which were causing extra queries. We can get away with
just using the user IDs, so pass those instead.
Select the submitter and repository along with a review request.
Reduce queries for screenshot and file attachment snippets on comments.

Comments for screenshots and file attachments caused extra queries per
comment, particularly on images during the process of providing the
snippet of the screenshot.

Since we already fetch the screenshots and file attachments, just build
another ID map and re-associate the screenshots and file attachments
before handing them off to the template.
Optimize the diff viewer page.

The diff viewer page was performing excessive queries for comments and
reviews. Now we pre-compute those, and diffsets, before rendering the
page.
Merge branch 'optimizations/review-requests' into release-1.6.x
Added live updates to timestamps.

Our timestamps have always shown that something happened "x minutes ago"
or "x years ago" or whatever. Unfortunately, with the caching, this
can get "stuck," and it's always wrong anyway since you may be on a page
for a while and the timestamps never updated.

Now we have live updating of all the timestamps. This works similarly to
Django's timesince, except it will update every minute. It also makes it
easier to cache the pages without having that data stored.

This makes use of a jQuery plugin I wrote, jquery-timesince, which
will be maintained at https://github.com/chipx86/jquery-timesince. This
plugin implements the same logic as Django's own timesince filter.