code_junkie

How to combine 2 or more querysets in a Django view?

Nov 13th, 2011
146
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.88 KB | None | 0 0
  1. result_list = []
  2. page_list = Page.objects.filter(Q(title__icontains=cleaned_search_term) | Q(body__icontains=cleaned_search_term))
  3. article_list = Article.objects.filter(Q(title__icontains=cleaned_search_term) | Q(body__icontains=cleaned_search_term) | Q(tags__icontains=cleaned_search_term))
  4. post_list = Post.objects.filter(Q(title__icontains=cleaned_search_term) | Q(body__icontains=cleaned_search_term) | Q(tags__icontains=cleaned_search_term))
  5.  
  6. for x in page_list:
  7. result_list.append(x)
  8. for x in article_list:
  9. result_list.append(x)
  10. for x in post_list:
  11. result_list.append(x)
  12.  
  13. return object_list(request, queryset=result_list, template_object_name='result',
  14. paginate_by=10, extra_context={'search_term': search_term},
  15. template_name="search/result_list.html")
  16.  
  17. from itertools import chain
  18. result_list = list(chain(page_list, article_list, post_list))
  19.  
  20. result_list = sorted(
  21. chain(page_list, article_list, post_list),
  22. key=lambda instance: instance.date_created)
  23.  
  24. from operator import attrgetter
  25. result_list = sorted(
  26. chain(page_list, article_list, post_list),
  27. key=attrgetter('date_created'))
  28.  
  29. from itertools import islice, chain
  30.  
  31. class QuerySetChain(object):
  32. """
  33. Chains multiple subquerysets (possibly of different models) and behaves as
  34. one queryset. Supports minimal methods needed for use with
  35. django.core.paginator.
  36. """
  37.  
  38. def __init__(self, *subquerysets):
  39. self.querysets = subquerysets
  40.  
  41. def count(self):
  42. """
  43. Performs a .count() for all subquerysets and returns the number of
  44. records as an integer.
  45. """
  46. return sum(qs.count() for qs in self.querysets)
  47.  
  48. def _clone(self):
  49. "Returns a clone of this queryset chain"
  50. return self.__class__(*self.querysets)
  51.  
  52. def _all(self):
  53. "Iterates records in all subquerysets"
  54. return chain(*self.querysets)
  55.  
  56. def __getitem__(self, ndx):
  57. """
  58. Retrieves an item or slice from the chained set of results from all
  59. subquerysets.
  60. """
  61. if type(ndx) is slice:
  62. return list(islice(self._all(), ndx.start, ndx.stop, ndx.step or 1))
  63. else:
  64. return islice(self._all(), ndx, ndx+1).next()
  65.  
  66. pages = Page.objects.filter(Q(title__icontains=cleaned_search_term) |
  67. Q(body__icontains=cleaned_search_term))
  68. articles = Article.objects.filter(Q(title__icontains=cleaned_search_term) |
  69. Q(body__icontains=cleaned_search_term) |
  70. Q(tags__icontains=cleaned_search_term))
  71. posts = Post.objects.filter(Q(title__icontains=cleaned_search_term) |
  72. Q(body__icontains=cleaned_search_term) |
  73. Q(tags__icontains=cleaned_search_term))
  74. matches = QuerySetChain(pages, articles, posts)
  75.  
  76. matches = pages | articles | posts
Add Comment
Please, Sign In to add comment