def search(request): # TODO: move to form if 'action' in request.GET: action = request.GET['action'] #FIXME: show_user for anonymous raise exception, #django bug http://code.djangoproject.com/changeset/14087 :| groups = request.user.groups.all() or [ ] #removed after django > 1.2.3 release topics = Topic.objects.filter(deleted=False).filter( Q(forum__category__groups__in=groups) | \ Q(forum__category__groups__isnull=True)) if action == 'show_24h': date = datetime.today() - timedelta(1) topics = topics.filter(created__gte=date) elif action == 'show_new': try: last_read = PostTracking.objects.get( user=request.user).last_read except PostTracking.DoesNotExist: last_read = None if last_read: topics = topics.filter(last_post__updated__gte=last_read).all() else: #searching more than forum_settings.SEARCH_PAGE_SIZE in this way - not good idea :] topics = [ topic for topic in topics[:forum_settings.SEARCH_PAGE_SIZE] if forum_extras.has_unreads(topic, request.user) ] elif action == 'show_unanswered': topics = topics.filter(post_count=1) elif action == 'show_subscriptions': topics = topics.filter(subscribers__id=request.user.id) elif action == 'show_user': user_id = request.GET['user_id'] posts = Post.objects.filter(deleted=False, user__id=user_id) topics = [post.topic for post in posts if post.topic in topics] elif action == 'search': keywords = request.GET.get('keywords') author = request.GET.get('author') forum = request.GET.get('forum') search_in = request.GET.get('search_in') sort_by = request.GET.get('sort_by') sort_dir = request.GET.get('sort_dir') if not (keywords or author): return HttpResponseRedirect(reverse('djangobb:search')) query = SearchQuerySet().models(Post).filter(deleted=0) if author: query = query.filter(author__username=author) if forum != u'0': query = query.filter(forum__id=forum) if keywords: if search_in == 'all': query = query.filter( SQ(topic=keywords) | SQ(text=keywords)) elif search_in == 'message': query = query.filter(text=keywords) elif search_in == 'topic': query = query.filter(topic=keywords) # add exlusions for categories user does not have access too for category in Category.objects.all(): if not category.has_access(request.user): query = query.exclude(category=category) order = { '0': 'created', '1': 'author', '2': 'topic', '3': 'forum' }.get(sort_by, 'created') if sort_dir == 'DESC': order = '-' + order posts = query.order_by(order) if 'topics' in request.GET['show_as']: return render(request, 'djangobb_forum/search_topics.html', {'results': TopicFromPostResult(posts)}) elif 'posts' in request.GET['show_as']: return render(request, 'djangobb_forum/search_posts.html', {'results': posts}) return render(request, 'djangobb_forum/search_topics.html', {'results': topics}) else: form = PostSearchForm() return render(request, 'djangobb_forum/search_form.html', { 'categories': Category.objects.all(), 'form': form, })
def search(request): # TODO: used forms in every search type def _render_search_form(form=None): return render(request, 'djangobb_forum/search_form.html', {'categories': Category.objects.all(), 'form': form, }) if not 'action' in request.GET: return _render_search_form(form=PostSearchForm()) if request.GET.get("show_as") == "posts": show_as_posts = True template_name = 'djangobb_forum/search_posts.html' else: show_as_posts = False template_name = 'djangobb_forum/search_topics.html' context = {} # Create 'user viewable' pre-filtered topics/posts querysets viewable_category = Category.objects.all() topics = Topic.objects.all().order_by("-last_post__created") posts = Post.objects.all().order_by('-created') user = request.user if not user.is_superuser: user_groups = user.groups.all() or [] # need 'or []' for anonymous user otherwise: 'EmptyManager' object is not iterable viewable_category = viewable_category.filter(Q(groups__in=user_groups) | Q(groups__isnull=True)) topics = Topic.objects.filter(forum__category__in=viewable_category) posts = Post.objects.filter(topic__forum__category__in=viewable_category) base_url = None _generic_context = True action = request.GET['action'] if action == 'show_24h': date = timezone.now() - timedelta(days=1) if show_as_posts: context["posts"] = posts.filter(Q(created__gte=date) | Q(updated__gte=date)) else: context["topics"] = topics.filter(Q(last_post__created__gte=date) | Q(last_post__updated__gte=date)) _generic_context = False elif action == 'show_new': if not user.is_authenticated(): raise Http404("Search 'show_new' not available for anonymous user.") try: last_read = PostTracking.objects.get(user=user).last_read except PostTracking.DoesNotExist: last_read = None if last_read: if show_as_posts: context["posts"] = posts.filter(Q(created__gte=last_read) | Q(updated__gte=last_read)) else: context["topics"] = topics.filter(Q(last_post__created__gte=last_read) | Q(last_post__updated__gte=last_read)) _generic_context = False else: #searching more than forum_settings.SEARCH_PAGE_SIZE in this way - not good idea :] topics_id = [topic.id for topic in topics[:forum_settings.SEARCH_PAGE_SIZE] if forum_extras.has_unreads(topic, user)] topics = Topic.objects.filter(id__in=topics_id) # to create QuerySet elif action == 'show_unanswered': topics = topics.filter(post_count=1) elif action == 'show_subscriptions': topics = topics.filter(subscribers__id=user.id) elif action == 'show_user': # Show all posts from user or topics started by user if not user.is_authenticated(): raise Http404("Search 'show_user' not available for anonymous user.") user_id = request.GET.get("user_id", user.id) try: user_id = int(user_id) except ValueError: raise SuspiciousOperation() if user_id != user.id: try: search_user = User.objects.get(id=user_id) except User.DoesNotExist: messages.error(request, _("Error: User unknown!")) return HttpResponseRedirect(request.path) messages.info(request, _("Filter by user '%(username)s'.") % {'username': search_user.username}) if show_as_posts: posts = posts.filter(user__id=user_id) else: # show as topic topics = topics.filter(posts__user__id=user_id).order_by("-last_post__created").distinct() base_url = "?action=show_user&user_id=%s&show_as=" % user_id elif action == 'search': form = PostSearchForm(request.GET) if not form.is_valid(): return _render_search_form(form) keywords = form.cleaned_data['keywords'] author = form.cleaned_data['author'] forum = form.cleaned_data['forum'] search_in = form.cleaned_data['search_in'] sort_by = form.cleaned_data['sort_by'] sort_dir = form.cleaned_data['sort_dir'] query = SearchQuerySet().models(Post) if author: query = query.filter(author__username=author) if forum != '0': query = query.filter(forum__id=forum) if keywords: if search_in == 'all': query = query.filter(SQ(topic=keywords) | SQ(text=keywords)) elif search_in == 'message': query = query.filter(text=keywords) elif search_in == 'topic': query = query.filter(topic=keywords) order = {'0': 'created', '1': 'author', '2': 'topic', '3': 'forum'}.get(sort_by, 'created') if sort_dir == 'DESC': order = '-' + order posts = query.order_by(order) if not show_as_posts: # TODO: We have here a problem to get a list of topics without double entries. # Maybe we must add a search index over topics? # Info: If whoosh backend used, setup HAYSTACK_ITERATOR_LOAD_PER_QUERY # to a higher number to speed up post_pks = posts.values_list("pk", flat=True) context["topics"] = topics.filter(posts__in=post_pks).distinct() else: # FIXME: How to use the pre-filtered query from above? posts = posts.filter(topic__forum__category__in=viewable_category) context["posts"] = posts get_query_dict = request.GET.copy() get_query_dict.pop("show_as") base_url = "?%s&show_as=" % get_query_dict.urlencode() _generic_context = False if _generic_context: if show_as_posts: context["posts"] = posts.filter(topic__in=topics).order_by('-created') else: context["topics"] = topics if base_url is None: base_url = "?action=%s&show_as=" % action if show_as_posts: context["as_topic_url"] = base_url + "topics" post_count = context["posts"].count() messages.success(request, _("Found %i posts.") % post_count) else: context["as_post_url"] = base_url + "posts" topic_count = context["topics"].count() messages.success(request, _("Found %i topics.") % topic_count) return render(request, template_name, context)
def search(request): # TODO: used forms in every search type def _render_search_form(form=None): return render(request, 'djangobb_forum/search_form.html', { 'categories': Category.objects.all(), 'form': form, }) if not 'action' in request.GET: return _render_search_form(form=PostSearchForm()) if request.GET.get("show_as") == "posts": show_as_posts = True template_name = 'djangobb_forum/search_posts.html' else: show_as_posts = False template_name = 'djangobb_forum/search_topics.html' context = {} # Create 'user viewable' pre-filtered topics/posts querysets viewable_category = Category.objects.all() topics = Topic.objects.all().order_by("-last_post__created") posts = Post.objects.all().order_by('-created') user = request.user if not user.is_superuser: user_groups = user.groups.all() or [ ] # need 'or []' for anonymous user otherwise: 'EmptyManager' object is not iterable viewable_category = viewable_category.filter( Q(groups__in=user_groups) | Q(groups__isnull=True)) topics = Topic.objects.filter(forum__category__in=viewable_category) posts = Post.objects.filter( topic__forum__category__in=viewable_category) base_url = None _generic_context = True action = request.GET['action'] if action == 'show_24h': date = datetime.now() - timedelta(days=1) if show_as_posts: context["posts"] = posts.filter( Q(created__gte=date) | Q(updated__gte=date)) else: context["topics"] = topics.filter( Q(last_post__created__gte=date) | Q(last_post__updated__gte=date)) _generic_context = False elif action == 'show_new': if not user.is_authenticated(): raise Http404( "Search 'show_new' not available for anonymous user.") try: last_read = PostTracking.objects.get(user=user).last_read except PostTracking.DoesNotExist: last_read = None if last_read: if show_as_posts: context["posts"] = posts.filter( Q(created__gte=last_read) | Q(updated__gte=last_read)) else: context["topics"] = topics.filter( Q(last_post__created__gte=last_read) | Q(last_post__updated__gte=last_read)) _generic_context = False else: #searching more than forum_settings.SEARCH_PAGE_SIZE in this way - not good idea :] topics = [ topic for topic in topics[:forum_settings.SEARCH_PAGE_SIZE] if forum_extras.has_unreads(topic, user) ] elif action == 'show_unanswered': topics = topics.filter(post_count=1) elif action == 'show_subscriptions': topics = topics.filter(subscribers__id=user.id) elif action == 'show_user': # Show all posts from user or topics started by user if not user.is_authenticated(): raise Http404( "Search 'show_user' not available for anonymous user.") if user.is_staff: user_id = request.GET.get("user_id", user.id) user_id = int(user_id) if user_id != user.id: search_user = User.objects.get(id=user_id) messages.info(request, "Filter by user '%s'." % search_user.username) else: user_id = user.id if show_as_posts: posts = posts.filter(user__id=user_id) else: # show as topic topics = topics.filter(posts__user__id=user_id).order_by( "-last_post__created").distinct() base_url = "?action=show_user&user_id=%s&show_as=" % user_id elif action == 'search': form = PostSearchForm(request.GET) if not form.is_valid(): return _render_search_form(form) keywords = form.cleaned_data['keywords'] author = form.cleaned_data['author'] forum = form.cleaned_data['forum'] search_in = form.cleaned_data['search_in'] sort_by = form.cleaned_data['sort_by'] sort_dir = form.cleaned_data['sort_dir'] query = SearchQuerySet().models(Post) if author: query = query.filter(author__username=author) if forum != u'0': query = query.filter(forum__id=forum) if keywords: if search_in == 'all': query = query.filter(SQ(topic=keywords) | SQ(text=keywords)) elif search_in == 'message': query = query.filter(text=keywords) elif search_in == 'topic': query = query.filter(topic=keywords) order = { '0': 'created', '1': 'author', '2': 'topic', '3': 'forum' }.get(sort_by, 'created') if sort_dir == 'DESC': order = '-' + order posts = query.order_by(order) if not show_as_posts: # TODO: We have here a problem to get a list of topics without double entries. # Maybe we must add a search index over topics? # Info: If whoosh backend used, setup HAYSTACK_ITERATOR_LOAD_PER_QUERY # to a higher number to speed up post_pks = posts.values_list("pk", flat=True) context["topics"] = topics.filter(posts__in=post_pks).distinct() else: # FIXME: How to use the pre-filtered query from above? posts = posts.filter(topic__forum__category__in=viewable_category) context["posts"] = posts get_query_dict = request.GET.copy() get_query_dict.pop("show_as") base_url = "?%s&show_as=" % get_query_dict.urlencode() _generic_context = False if _generic_context: if show_as_posts: context["posts"] = posts.filter( topic__in=topics).order_by('-created') else: context["topics"] = topics if base_url is None: base_url = "?action=%s&show_as=" % action if show_as_posts: context["as_topic_url"] = base_url + "topics" post_count = context["posts"].count() messages.success(request, _("Found %i posts.") % post_count) else: context["as_post_url"] = base_url + "posts" topic_count = context["topics"].count() messages.success(request, _("Found %i topics.") % topic_count) return render(request, template_name, context)