How to limit response size in django lamba query

Viewed 87

I know the typical way to limit queries within Django is to append [:10] to the end of the query, but I have a function that uses a functools.reduce(lambda and I'm unsure how to limit the query size. As it stands the query is taking way too long and fetching way too much data. What's the best way to limit this query and increase efficiency?

Here's the function:

    def get_threads_for_student_mentor(cls, student_id=None, mentor_id=None):
        clauses = []
        if student_id:
            clauses.append(models.Q(student_id=student_id))
        if mentor_id:
            clauses.append(models.Q(mentor_id=mentor_id))
        if len(clauses) == 0:
            raise ValueError("student_id and mentor_id cannot both be None")

        return cls.objects.filter(functools.reduce(lambda a, b: a & b, clauses))

I tried changing the return statement to return cls.objects.filter(functools.reduce(lambda a, b: a & b, clauses))[:5].all() and I also tried adding it to the append functions, as in clauses.append(models.Q(student_id=student_id)[:5]) but alas, nothing has works thus far. What am I doing wrong here? I'm sure it's just a silly mistake.

1 Answers

The way the filtering is constructed has no impact on limiting the number of results. You can work with:

return cls.objects.filter(functools.reduce(lambda a, b: a & b, clauses))[:5]

You can also simplify the filtering with:

def get_threads_for_student_mentor(cls, student_id=None, mentor_id=None):
    clauses = {}
    if student_id:
        clauses['student_id'] = student_id
    if mentor_id:
        clauses['mentor_id'] = mentor_id
    if not clauses:
        raise ValueError('student_id and mentor_id cannot both be None')

    return cls.objects.filter(**clauses)[:5]

cls should be a reference to the class, not an object of that class.

Related