Tuesday, March 29, 2011

Generic List View raises Attribute Error: "'function' object has no attribute '_clone'

I've written a simple search function that uses a db model based on
the one described in The Django Book tutorial (http://
www.djangobook.com/en/2.0/), using a generic list, and a Paginator.

Here is my view function:

def search (request):
"""Search by title or author name"""

if 'q' in request.POST and request.POST['q']:

query_term = request.POST['q']
context = { }

book_list =
Book.objects.filter(Q(authors__name__contains=query_term) |
Q(title__contains=query_term))
if len(book_list) == 0:
context['message'] = 'No matches found'
book_list = Book.objects.all() #
Book.objects.filter(Q(available=True)) also works

paginator = Paginator(book_list, 10) # Show 10 books per page

try:
page = int(request.GET.get('page', '1'))
except ValueError:
page = 1

try:
books = paginator.page(page)
except (EmptyPage, InvalidPage):
books = paginator.page(paginator.num_pages)

shopping_cart_count = 0
if "cart" in request.session:
shopping_cart_count = len(request.session['cart'])
context['shopping_cart'] = shopping_cart_count

return list_detail.object_list(request, queryset=books,
template_name='book_list.html', extra_context=context)

When there no matches for the query_term are found, the book_list is
simply Book.objects.all(), and the template is rendered correctly.

When, however, the query_term matches, I get this error:

Attribute Error: "'function' object has no attribute '_clone'

Supposedly, this is because the filtering does not produce a proper
QuerySet, which in turn, cannot be cloned by the generic view.

If, however, I change the no matches QuerySet from Book.objects.all()
to Book.objects.filter(Q(available=True)), the generic view works.

Both of the solutions I found suggest creating a new class which
builds a proper QuerySet from multiple filter lists (http://
djangosnippets.org/snippets/1103/ and
http://stackoverflow.com/questions/431628/how-to-combine-2-or-more-querysets-in-a-django-view/432666#432666),
but even using those gave me the same result.

I also tried removing the Q(authors__name__contains=query_term) filter
on Book, since authors is a ManyToMany relation, but that gave me the
same result as well.

Any suggestions?

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment