Replace many queryset count() calls with exists() calls.

Review Request #10389 — Created Jan. 23, 2019 and submitted — Latest diff uploaded

Review Board

We have many places in the codebase where we perform logic based on
whether there are entries found in a queryset. Many of these use
.count() and compare to 0, which requires actually counting all the
rows first in the database.

As an optimization, we now use .exists() instead. This is an
optimization provided by Django that limits the results to 1 row, clears
any fields and ordering, and just checks for the existence of one row of
data. This is more efficient, speeding up these checks and reducing work
on the database.

There's also a couple places where we were checking the contents of a
Many-to-Many table before adding or removing an item, which was redundant
as Django was already doing this. Those have been simplified, reducing

Unit tests passed.

Went through the affected parts of the product. Didn't hit any regressions.