Watson requiring Queryset objects, and not accepting lists, when registering models

47 views
Skip to first unread message

Patrick Heneghan

unread,
Jan 13, 2017, 8:19:14 AM1/13/17
to django-watson discussion group
Hi there - thanks for a great app! I'm impressed at how quickly I was able to get great search capability up and running.

I'm having a problem with one of the models I'm registering. It's a model where some objects are 'live' and some are 'hidden', so I've followed your instructions at https://github.com/etianen/django-watson/wiki/registering-models#only-displaying-live-search-results

I have defined a custom Manager for this particular model - but Watson appears to be compatible with this, so no problems there.

Where I believe the problem lies, is that my custom method does not return a Queryset - it returns a list. Why? Because I have to sort the results based on the value of a method. Queryset filtering does not support this, so I have to use a solution which eventually converts the Queryset to a list - example shown here: http://stackoverflow.com/a/6932807/3293805

Here is my actual code:

class EventManager(models.Manager):

    def get_upcoming_events(self, site=None, featured_only=False):
        events = self.get_queryset()
        events = events.filter(post_status=Post.ACTIVE)
        if featured_only == True:
            events = events.filter(featured=True)
        if site is not None:
            events = events.filter(site=site)
        # here we are sorting events in Python, not SQL. TODO: optimise if needed.
        events_with_a_next_start_time = [e for e in events if e.next_start_time() is not None]
        events_sorted_by_next_start_time = sorted(events_with_a_next_start_time, key = lambda a: a.next_start_time())
        return events_sorted_by_next_start_time

This solution works just fine if you're passing this list to a template in the context - templates handle Querysets and lists in the same way.

However, it appears that Watson requires that the results be a Queryset, as I'm getting this error:

TypeError: unhashable type: 'list'


(I can send you a full traceback if that would help)

I have managed to convert my list back to a Queryset (using this solution: http://stackoverflow.com/a/18608118/3293805), and now Watson works correctly.

However, I'm curious to know whether it might be possible to adapt Watson to accept either Querysets or lists? Is there any particular dependency on the object being a Queryset?

Best,
Patrick

Dave Hall

unread,
Jan 13, 2017, 9:46:32 AM1/13/17
to django-watson discussion group
Watson needs a queryset because it performs the full text search using the database engine's native filters.

Converting a list to a queryset has a fairly significant overhead, so it's not something I want to bake into Watson. If people want to do this in their own code, that's fine, but it's not something that I would personally bless.

Also, from a practically point of view, making every function across the Django ecosystem that requires a queryset polymorphic is quite an undertaking! Better to have a helper function than can be used to adapt a list to a queryset where needed.
--
You received this message because you are subscribed to the Google Groups "django-watson discussion group" group.
To unsubscribe from this group and stop receiving emails from it, send an email to django-watso...@googlegroups.com.
To post to this group, send email to django...@googlegroups.com.
Visit this group at https://groups.google.com/group/django-watson.
For more options, visit https://groups.google.com/d/optout.

Patrick Heneghan

unread,
Jan 13, 2017, 10:35:53 AM1/13/17
to django-watson discussion group
Hi Dave, thanks for your reply.

Fair enough - I understand now why Watson needs a Queryset. And, agreed, I would not suggest that converting a list back to a Queryset should be baked into Watson.

Good call on the helper function.

Best,
Patrick
Reply all
Reply to author
Forward
0 new messages