django, python :: reduce() of empty sequence with no initial value

1,770 views
Skip to first unread message

tyrrrr

unread,
Apr 22, 2009, 9:17:04 AM4/22/09
to Django users
Hi
I am trying to add a search view to an application I wrote in django
but my EntryManager() seems to be getting hung up on the last line of
code when django tries to call the url of the search.

This EntryManager() (models.py) is excellent for performing searches
in the django shell ($ python manage.py shell) like

x = Entry.objects.search('spam')
list(x)

for example

However when I attempt to visit the url of the search I am met with
the error " reduce() of empty sequence with no initial value " and a
reference to the last line of EntryManager()

return qs.filter(reduce(operator.or_, q_objects))
I use this method to strip multiple word queries and place underscores
between the words

type error:
reduce() of empty sequence with no initial value

The problems seems to be that the EntryManager() requires a string
from the beginning and I haven't been able to make it work without
one.

The rest of my code works perfectly.

Obviously the value will be empty before a query is made. What am I
doing wrong? Is there perhaps a better way to connect my search view
to this object?

ps: I am aware that this isn't exactly a very efficient, scalable or
long-term solution to my search issue. It is however important that I
get this work as a temporary solution before I move to whoosh/
haystack.

Thanks everyone!

//////////////////////
models.py

import operator
from django.db import models
from django.db.models import Q

class EntryManager(models.Manager):
def search(self, search_terms):
terms = [term.strip() for term in search_terms.split
()]
q_objects = []
for term in terms:
q_objects.append(Q(name__icontains=term))
q_objects.append(Q
(description__icontains=term))
qs = self.get_query_set()
return qs.filter(reduce(operator.or_, q_objects))

//////////////////////
views.py

def searching(request):
query_string = ''
if ('q' in request.GET) and request.GET['q'].strip():
query_string = request.GET['q'].strip()
results = Entry.objects.search(query_string)
return render_to_response("search_results.html",
{'query_string': query_string, 'results' : results})

//////////////////////
search_results.html

<div>Searched Results</div>

{%if results%}
{% for e in results%}
<a href=../{{e.slug}}>{{e.name}}</a></div>
{% endfor %}
{% else %} Nothing to see here...
{% endif %}

//////////////////////

tyrrrr

unread,
Apr 22, 2009, 10:48:28 AM4/22/09
to Django users
this is the error:

reduce() of empty sequence with no initial value

Request Method: GET
Request URL: http://dsfffffffffffffffffffff/search/
Exception Type: TypeError
Exception Value: reduce() of empty sequence with no initial value
Exception Location: /dsfffffffffffffffffffff/models.py in search,
line 59

views.py in searching
68. results = Entry.objects.search(query_string)

models.py in search
59. return qs.filter(reduce(operator.or_, q_objects))

Karen Tracey

unread,
Apr 22, 2009, 10:55:16 AM4/22/09
to django...@googlegroups.com
On Wed, Apr 22, 2009 at 10:48 AM, tyrrrr <electio...@gmail.com> wrote:

this is the error:

reduce() of empty sequence with no initial value

Request Method:         GET
Request URL:    http://dsfffffffffffffffffffff/search/
Exception Type:         TypeError
Exception Value:        reduce() of empty sequence with no initial value
Exception Location:     /dsfffffffffffffffffffff/models.py in search,
line 59

views.py in searching
 68. results = Entry.objects.search(query_string)

models.py in search
 59. return qs.filter(reduce(operator.or_, q_objects))

The error implies your q_objects is an empty sequence:

>>> import operator
>>> reduce(operator.or_, ())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: reduce() of empty sequence with no initial value

Which, looking at your code, seems to be exactly what you'd expect for a url that has no q in request.GET.  You can't call reduce on an empty sequence, so change your code to properly account for when it isn't given anything to search for.

Karen

tyrrrr

unread,
Apr 22, 2009, 11:00:37 AM4/22/09
to Django users
Yes. I realise that this is exactly the problem. Do you have some sort
of suggestion as to how one might do this?
My experience with this manager is calling it from the python shell.
I'm not exactly sure how I might do this.

Something like

if q
for term in terms:
q_objects.append(Q(name__icontains=term))
q_objects.append(Q
(description__icontains=term))
qs = self.get_query_set()
return qs.filter(reduce(operator.or_, q_objects))
else
do nothing?

I don't really know what to do :/

On 22 Apr, 10:55, Karen Tracey <kmtra...@gmail.com> wrote:

tyrrrr

unread,
Apr 22, 2009, 11:08:22 AM4/22/09
to Django users
I might add that it gives me exactly the same error if I try to fetch
a url with a query in it, for example:
asdjhakshd/search/?=purple
asdjhakshd/search/?=monkey_dishwasher
asdjhakshd/search/?=purple+monkey+dishwasher

Karen Tracey

unread,
Apr 22, 2009, 11:25:34 AM4/22/09
to django...@googlegroups.com
On Wed, Apr 22, 2009 at 11:08 AM, tyrrrr <electio...@gmail.com> wrote:

I might add that it gives me exactly the same error if I try to fetch
a url with a query in it, for example:
asdjhakshd/search/?=purple
asdjhakshd/search/?=monkey_dishwasher
asdjhakshd/search/?=purple+monkey+dishwasher

Those urls don't have a 'q' specified in the query string, which is what your code is looking for.  You want urls like 'asdjhakshd/search/?q=purple'.

As for how to avoid the error: what do you want to happen if there is nothing specified to search for?  Do you want to return all entries?  No entries?  Once you make that decision fix up the code in search to check for the case of an empty search string and simply return qs.all() or qs.none() instead of trying to do the qs.filter().

Karen


tyrrrr

unread,
Apr 22, 2009, 11:34:12 AM4/22/09
to Django users
Thank you so much!

On 22 Apr, 11:25, Karen Tracey <kmtra...@gmail.com> wrote:

tyrrrr

unread,
Apr 26, 2009, 11:29:25 AM4/26/09
to Django users
Here is the ultimate solution.

class EntryManager(models.Manager):
def search(self, search_terms):
terms = [term.strip() for term in search_terms.split
()]
qs = Entry.objects.all()
if terms:
q_objects = []
for term in terms:
q_objects.append(Q
(name__icontains=term))
q_objects.append(Q
(description__icontains=term))
qs = self.get_query_set()
return qs.filter(reduce(operator.or_,
q_objects))
return qs.none() #or qs.all() as the case may be

On 22 Apr, 11:34, tyrrrr <electioneer...@gmail.com> wrote:
> Thank you so much!
>
> On 22 Apr, 11:25, Karen Tracey <kmtra...@gmail.com> wrote:
>
> > On Wed, Apr 22, 2009 at 11:08 AM,tyrrrr<electioneer...@gmail.com> wrote:
>
> > > I might add that it gives me exactly the same error if I try to fetch
> > > a url with a query in it, for example:
> > > asdjhakshd/search/?=purple
> > > asdjhakshd/search/?=monkey_dishwasher
> > > asdjhakshd/search/?=purple+monkey+dishwasher
>
> > Those urls don't have a 'q' specified in the query string, which is what
> > your code is looking for.  You want urls like 'asdjhakshd/search/?q=purple'.
>
> > As for how to avoid the error: what do you want to happen if there is
> > nothing specified to search for?  Do you want to return all entries?  No
> > entries?  Once you make that decision fix up the code in search to check for
> > the case of an empty search string and simply return qs.all() or qs.none()
> > instead of trying to do the qs.filter().
>
> > Karen
>
> > > On 22 Apr, 11:00,tyrrrr<electioneer...@gmail.com> wrote:
> > > > Yes. I realise that this is exactly the problem. Do you have some sort
> > > > of suggestion as to how one might do this?
> > > > My experience with this manager is calling it from the python shell.
> > > > I'm not exactly sure how I might do this.
>
> > > > Something like
>
> > > > if q
> > > > for term in terms:
> > > >                         q_objects.append(Q(name__icontains=term))
> > > >                         q_objects.append(Q
> > > > (description__icontains=term))
> > > >                 qs = self.get_query_set()
> > > >                 return qs.filter(reduce(operator.or_, q_objects))
> > > > else
> > > > do nothing?
>
> > > > I don't really know what to do :/
>
> > > > On 22 Apr, 10:55, Karen Tracey <kmtra...@gmail.com> wrote:
>
> > > > > On Wed, Apr 22, 2009 at 10:48 AM,tyrrrr<electioneer...@gmail.com>
Reply all
Reply to author
Forward
0 new messages