Ticket 1257

Fixes issue #1257 although there are a couple problems. 

1) The change noticeably slows down loading the dashboard stats. It seems that (at least in this context) any query which involves both StudentRegistration and StudentSubjectInterest slows down the query dramatically, and this dashboard statistic should take into account both cases. It's tolerable on my devserver but I have no idea how long it would take with the full database. (I also note that it's only tolerable because .count() is much faster than len(). An attempt to actually retrieve the entries could take an obscenely long time.) Tej thinks this is probably because Django is merging StudentRegistration and SSI in the process of making this query. Concatenating the two querysets into a list would probably be faster, but then it wouldn't be a queryset. (It would, at least, require JSONDataModule.stats() to account for this change.)
2) For the function I changed, if QObject = True, students() will return the Q object GoodReg in the return dict, which in an ideal world would be consistent with when QObject = False (in which case it should return ESPUser.objects.filter(GoodReg).distinct() instead), but unfortunately, it doesn't work this way (at least on my devserver). In particular, print ESPUser.objects.filter(GoodReg).distinct().count() outputs a SMALLER count than print ESPUser.objects.filter(SubjPar & SubjUnexpired).distinct().count(), which is ridiculous, because GoodReg = (SubjPar & SubjUnexpired) | (Par & Unexpired). I also printed GoodReg, and the resulting query looks correct. This is why QObject = False causes the function to directly union the querysets together instead of looking up the OR of the Q objects. The point is, the return value of QObject= True and QObject = False will give inconsistent results.

But at least the dashboard looks like it's fixed here.