def question_list()

in kitsune/questions/views.py [0:0]


def question_list(request, product_slug=None, topic_slug=None):
    """View the list of questions."""
    if settings.DISABLE_QUESTIONS_LIST_GLOBAL:
        messages.add_message(request, messages.WARNING, "You cannot list questions at this time.")
        return HttpResponseRedirect("/")

    topic_navigation = any(
        [
            request.resolver_match.url_name == "questions.list_by_topic",
            topic_slug and not product_slug,
        ]
    )
    filter_ = request.GET.get("filter")
    owner = request.GET.get("owner", request.session.get("questions_owner", "all"))
    show = request.GET.get("show")
    # Show defaults to NEEDS ATTENTION
    if show not in FILTER_GROUPS:
        show = "needs-attention"

    tagged = request.GET.get("tagged")
    tags = None
    topic_slug = request.GET.get("topic", "") or topic_slug

    order = request.GET.get("order", "updated")
    if order not in ORDER_BY:
        order = "updated"
    sort = request.GET.get("sort", "desc")

    product_slugs = product_slug.split(",") if product_slug else []
    products = []

    if product_slugs and ("all" not in product_slugs):
        for slug in product_slugs:
            products.append(get_object_or_404(Product, slug=slug))
    else:
        # We want all products (no product filtering at all).
        if settings.DISABLE_QUESTIONS_LIST_ALL:
            messages.add_message(
                request, messages.WARNING, "You cannot list all questions at this time."
            )
            return HttpResponseRedirect("/")
        products = Product.active.with_question_forums(request)

    multiple = (len(products) > 1) or ("all" in product_slugs)
    product_with_aaq = False
    if products and not multiple:
        product_with_aaq = has_aaq_config(products[0])

    topics = []

    if topic_slug:
        try:
            topic_history = TopicSlugHistory.objects.get(slug=topic_slug)

            return redirect(question_list, topic_slug=topic_history.topic.slug)
        except TopicSlugHistory.DoesNotExist:
            ...
        topics = Topic.active.filter(visible=True, slug=topic_slug)
        if not topics:
            raise Http404()

    question_qs = Question.objects

    if filter_ not in FILTER_GROUPS[show]:
        filter_ = None

    match filter_:
        case "new":
            question_qs = question_qs.new()
        case "unhelpful-answers":
            question_qs = question_qs.unhelpful_answers()
        case "needsinfo":
            question_qs = question_qs.needs_info()
        case "solution-provided":
            question_qs = question_qs.solution_provided()
        case "solved":
            question_qs = question_qs.solved()
        case "locked":
            question_qs = question_qs.locked()
        case "recently-unanswered":
            question_qs = question_qs.recently_unanswered()
        case _:
            if show == "needs-attention":
                question_qs = question_qs.needs_attention()
            if show == "responded":
                question_qs = question_qs.responded()
            if show == "done":
                question_qs = question_qs.done()

    question_qs = question_qs.select_related("creator", "last_answer", "last_answer__creator")
    # Exclude questions over 90 days old without an answer or older than 2 years or created
    # by deactivated users. Use "__range" to ensure the database index is used in Postgres.
    today = date.today()
    question_qs = (
        question_qs.exclude(
            created__range=(datetime.min, today - timedelta(days=90)), num_answers=0
        )
        .filter(creator__is_active=True)
        .filter(updated__range=(today - timedelta(days=365 * 2), Now()))
    )

    question_qs = question_qs.prefetch_related("topic", "product")

    if not request.user.has_perm("flagit.can_moderate"):
        question_qs = question_qs.filter(is_spam=False)

    if owner == "mine" and request.user.is_authenticated:
        criteria = Q(answers__creator=request.user) | Q(creator=request.user)
        question_qs = question_qs.filter(criteria).distinct()
    else:
        owner = None

    feed_urls = (
        (
            urlparams(reverse("questions.feed"), product=product_slug, topic=topic_slug),
            QuestionsFeed().title(),
        ),
    )

    if tagged:
        tag_slugs = tagged.split(",")
        tags = SumoTag.objects.active().filter(slug__in=tag_slugs)
        if tags:
            for t in tags:
                question_qs = question_qs.filter(tags__name__in=[t.name])
            if len(tags) == 1:
                feed_urls += (
                    (
                        reverse("questions.tagged_feed", args=[tags[0].slug]),
                        TaggedQuestionsFeed().title(tags[0]),
                    ),
                )
        else:
            question_qs = Question.objects.none()

    # Filter by products.
    if products:
        question_qs = question_qs.filter(product__in=products)

    # Filter by topic.
    if topics:
        # This filter will match if any of the topics on a question have the
        # correct id.
        question_qs = question_qs.filter(topic__in=topics)

    # Filter by locale for AAQ locales, and by locale + default for others.
    if request.LANGUAGE_CODE in AAQConfig.objects.locales_list():
        locale_query = Q(locale=request.LANGUAGE_CODE)
    else:
        locale_query = Q(locale=request.LANGUAGE_CODE)
        locale_query |= Q(locale=settings.WIKI_DEFAULT_LANGUAGE)

    question_qs = question_qs.filter(locale_query)

    # Set the order.
    # Set a default value if a user requested a non existing order parameter
    order_by = ORDER_BY.get(order, ["updated"])[0]
    question_qs = question_qs.order_by(order_by if sort == "asc" else "-%s" % order_by)

    try:
        questions_page = simple_paginate(request, question_qs, per_page=config.QUESTIONS_PER_PAGE)
    except (PageNotAnInteger, EmptyPage):
        # If we aren't on page 1, redirect there.
        # TODO: Is 404 more appropriate?
        if request.GET.get("page", "1") != "1":
            url = build_paged_url(request)
            return HttpResponseRedirect(urlparams(url, page=1))

    # Recent answered stats
    extra_filters = locale_query

    if products:
        extra_filters &= Q(product__in=products)

    recent_asked_count = Question.recent_asked_count(extra_filters)
    recent_unanswered_count = Question.recent_unanswered_count(extra_filters)
    if recent_asked_count:
        recent_answered_percent = int(
            (float(recent_asked_count - recent_unanswered_count) / recent_asked_count) * 100
        )
    else:
        recent_answered_percent = 0

    # List of products to fill the selector.
    product_list = Product.active.filter(visible=True)

    # List of topics to fill the selector.
    topic_list = Topic.active.filter(in_aaq=True, visible=True)
    if product_slugs:
        topic_list = topic_list.filter(products__in=products).distinct()
    else:
        topic_list = topic_list.filter(in_nav=True)

    # Store current filters in the session
    if request.user.is_authenticated:
        request.session["questions_owner"] = owner

    data = {
        "questions": questions_page,
        "feeds": feed_urls,
        "filter": filter_,
        "owner": owner,
        "show": show,
        "filters": FILTER_GROUPS[show],
        "order": order,
        "orders": ORDER_BY,
        "sort": sort,
        "tags": tags,
        "tagged": tagged,
        "recent_asked_count": recent_asked_count,
        "recent_unanswered_count": recent_unanswered_count,
        "recent_answered_percent": recent_answered_percent,
        "product_list": product_list,
        "products": products,
        "topic_slug": topic_slug,
        "multiple_products": multiple,
        "all_products": product_slug == "all" or topic_navigation,
        "topic_list": topic_list,
        "topics": topics,
        "selected_topic_slug": topics[0].slug if topics else None,
        "product_slug": product_slug,
        "topic_navigation": topic_navigation,
        "has_aaq_config": product_with_aaq,
    }

    if products:
        data["ga_products"] = f"/{'/'.join(product.slug for product in products)}/"

    return render(request, "questions/question_list.html", data)