views:

40

answers:

2

I'm currently building a simple search method for some designs. The query searches both the name of the author and the text of the design. The problem: what happens when the database has 300,000 designs and I want to paginate the results? If I pass a page variable, then each time a user switches to a different page, the query is executed again.

What is the best way to solve this problem? Is it properly caching as many searches as possible? Is it storing a certain amount in session data?

"""
Searches by screenname or design text
"""
def search_designs(request):

    designs = None
    words   = None

    if request.method == 'POST':
        q     = request.POST['search']
        words = q.split()

        # Get all approved designs
        designs = Design.objects.filter(status=2)

        for w in words:
            designs = designs.filter(name__icontains=w) | designs.filter(author__profile__screenname__icontains=w)

    vars = RequestContext(request, 
    {
        'results' : designs,
        'words'   : words,
    })
    return render_to_response("search_test.html", vars)
+2  A: 

I would check out django-pagination. It will handle pagination for you on the template level. It's really easy to integrate.

Zach
I'm not worried about pagination as a singular concept (I've built my own), I'm concerned about how to maintain a 'state' with the dynamically searched results. Otherwise, every time you go to a page, you're essentially saying "Django, search the entire database again for the same results and give me page (x)"
Sebastian
django-pagination if done properly will only retrieve the objects it needs for the current page. perhaps the one you've written wasn't done properly?
Brandon H
There is not need to create your own pagination, this on is very good. Because `QuerySets` are lazy, only the necessary items will be fetched from the database as long as you don't do anything in the view that forces evaluation.
Zach
+1  A: 

So you're trying to save all the results, so when a user moves through the pages the database is not accessed again, right? Since they're dynamic searches, the only way to do so is to cache these pages, still pages that have not been visited yet, will not be cached. So the only benefit is if the user goes back to previous pages. I don't think you will gain many benefits from this practice.

It's perfectly fine to execute one query every time a user loads a page.

Also, if on your template you're iterating through the query set, each iteration will hit the database. Just before you pass in the query set to the template, use my_query_set = list(my_query_set) to avoid multiple database hits.

Luiz C.
Luiz, the documentation states: "A QuerySet is iterable, and it executes its database query the first time you iterate over it." Thanks for letting me know about list() though. That is good to know.
Sebastian