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)