I have a complex database model configured in Django, and I have to do a series of calculations based on filter data. I have a Test
object, a TestAttempt
object TestAttempt
and a UserProfile
object (with a foreign key for verification and a foreign key back to the user file). There is a method that I run on TestAttempt
that calculates the test score (based on a number of options provided by the user, compared to the correct answers associated with each test). And another method that I run on Test
, which calculates the average test score based on each of the associated TestAttempt
. But sometimes I only need an average value based on the provided subset of the associated TestAttempt
that are associated with a specific set of UserProfiles
. Therefore, instead of calculating the average test score for a particular test as follows:
[x.score() for x in self.test_attempts.all()]
and then averaging these values. I make a request like this:
[x.score() for x in self.test_attempts.filter(profile__id__in=user_id_list).all()]
where user_id_list
is a specific subset of the UserProfile identifier for which I want to find the average grade of the test as a list. My question is this: if user_id_list
really the entire UserProfile
set (so the filter will return the same as self.test_attempts.all()
), and most of the time it will be whether it pays for checking this case, and if it does not filter at all ? or __in is quite effective, even if user_id_list
contains all users, it will be more efficient to run the filter. Also, do I need to worry about making the result of test_attempts distinct ()? or can't they include duplicates with the structure of my request?
EDIT: for anyone interested in a raw SQL query, it looks like this without a filter:
SELECT "mc_grades_testattempt"."id", "mc_grades_testattempt"."date", "mc_grades_testattempt"."test_id", "mc_grades_testattempt"."student_id" FROM "mc_grades_testattempt" WHERE "mc_grades_testattempt"."test_id" = 1
and this is with a filter:
SELECT "mc_grades_testattempt"."id", "mc_grades_testattempt"."date", "mc_grades_testattempt"."test_id", "mc_grades_testattempt"."student_id" FROM "mc_grades_testattempt" INNER JOIN "mc_grades_userprofile" ON ("mc_grades_testattempt"."student_id" = "mc_grades_userprofile"."id") WHERE ("mc_grades_testattempt"."test_id" = 1 AND "mc_grades_userprofile"."user_id" IN (1, 2, 3))
note that the array (1,2,3) is just an example