+def _word_starts_with(name, prefix):
+ """returns a Q object getting models having `name` contain a word
+ starting with `prefix`
+ """
+ kwargs = {}
+ if settings.DATABASE_ENGINE in ('mysql', 'postgresql_psycopg2', 'postgresql'):
+ # we must escape `prefix` so that it only matches literally
+ for special in r'\^$.*+?|(){}[]':
+ prefix = prefix.replace(special, '\\' + special)
+
+ # we could use a [[:<:]] (word start),
+ # but we want both `xy` and `(xy` to catch `(xyz)`
+ kwargs['%s__iregex' % name] = u"(^|[^[:alpha:]])%s" % prefix
+ else:
+ # don't know how to do a generic regex
+ # checking for simple icontain instead
+ kwargs['%s__icontains' % name] = prefix
+ return Q(**kwargs)
+
+
+def _tags_exact_matches(prefix, user):
+ book_stubs = models.BookStub.objects.filter(title__iexact = prefix)
+ books = models.Book.objects.filter(title__iexact = prefix)
+ book_stubs = filter(lambda x: x not in books, book_stubs)
+ tags = models.Tag.objects.filter(name__iexact = prefix)
+ if user.is_authenticated():
+ tags = tags.filter(~Q(category='book') & (~Q(category='set') | Q(user=user)))
+ else:
+ tags = tags.filter(~Q(category='book') & ~Q(category='set'))
+
+ return list(books) + list(tags) + list(book_stubs)
+
+