views:

140

answers:

3

I have a basic search view. It currently queries the db for any objects from a particular client. The view code is as follows:

def search_page(request):
        form = PrdSearchForm() 
        prdlinks = [] 
        show_results = True 
        if request.GET.has_key('query'): 
                show_results = True 
                query = request.GET['query'].strip() 
                if query:
                        form = PrdSearchForm({'query' : query}) 
                        prdlinks = \
                                ProjectRecord.objects.filter(client__icontains=query)

        if len(prdlinks) >= 1:
            records = ProjectRecord.objects.filter(client__icontains=query)
            t = get_template('org_list_client.html')
            html = t.render(Context({'records': records}))
            return HttpResponse(html)

        else:
            tpl = "prd_search.html"
            variables = RequestContext(request, { 'form': form, 
            'prdlinks': prdlinks, 
            'show_results': show_results}) 
            return render_to_response(tpl, variables)

I'd like for the search field to check both for objects by client AND account. This, I think, would involve altering this code:

if query:
        form = PrdSearchForm({'query' : query}) 
        prdlinks = \
                 ProjectRecord.objects.filter(client__icontains=query)

to include ProjectRecord.objects.filter(account__icontains=query). Can anyone help with the syntax, or is there more involved with what I'm trying to accomplish?

A: 

You can try to chain filters, like:

>>> ProjectRecord.objects.filter(
...    client__icontains=query).filter(account__icontains=query)

This will first filter the clients, which contain the query, then filter this result queryset where the account also contains query.

General form:

>>> Entry.objects.filter(
...     headline__startswith='What'
... ).exclude(
...     pub_date__gte=datetime.now()
... ).filter(
...     pub_date__gte=datetime(2005, 1, 1)
... )

Further useful examples are included in the documentation:

The MYYN
I don't believe this type of chain is workable in this situation. For example, if my client is, say XEROX, and that client has 2 accounts with me "copier foo" and "copier bar". If "copier bar" is my search term, the filter searches for clients named "copier bar" and returns a queryset of 0 objects for the secondary account filter.Will continue to search the documentation though. Gracias.
kjarsenal
A: 

Restructured the view code to separate the client records(prdlinks) from the account records(acclinks) and handled them separately. Wasn't sure if it would work (it does) and am still not sure if this is the most efficient way to write the code (probably isn't). In any event, here is the revised code:

def search_page(request):
        form = PrdSearchForm() 
        prdlinks = []
        **acclinks = []**
        show_results = True 
        if request.GET.has_key('query'): 
                show_results = True 
                query = request.GET['query'].strip() 
                if query:
                        form = PrdSearchForm({'query' : query}) 
                        prdlinks = \
                                ProjectRecord.objects.filter(client__icontains=query)
                        **acclinks = \
                                ProjectRecord.objects.filter(account__icontains=query)**

        if len(prdlinks) >= 1:
            records = ProjectRecord.objects.filter(client__icontains=query)
            t = get_template('org_list_client.html')
            html = t.render(Context({'records': records}))
            return HttpResponse(html)

        **elif len(acclinks) >= 1:
            records = ProjectRecord.objects.filter(account__icontains=query)
            t = get_template('org_list_account.html')
            html = t.render(Context({'records': records}))
            return HttpResponse(html)**

        else:
            tpl = "prd_search.html"
            variables = RequestContext(request, { 'form': form, 
            'prdlinks': prdlinks, 
            'show_results': show_results}) 
            return render_to_response(tpl, variables)
kjarsenal
A: 

I think you're looking for the Q object (as refrenced by The MYYN)

from django.db.models import Q

records=ProjectRecord.objects.filter(
  Q(client__icontains=query) |
  Q(account__icontains=query)
)

complex-lookups-with-q-objects

czarchaic
Tried importing the Q object. Problem with that is, if I don't separate prdlinks from acclinks, the Q query will work for client objects because it satisfies the third "if" query: "if len(prdlinks) >= 1:..."However if the search term is an account name (as opposed to client name),the query DOES return a "prdlink" but DOESN'T return any records because the if query is looking for (client__icontains=query). The result is that it renders an empty template. (and doesn't continue on to evaluate the following "elif" query that asks for (account__icontains=query)).
kjarsenal