Source code for django_help.utils.queryset

"""Queryset utilities for the Django Help app."""

from __future__ import annotations

import logging
from typing import TYPE_CHECKING
from typing import Union
from urllib.parse import unquote

from django.db.models import F
from django.http import HttpRequest
from translated_fields import to_attribute

from django_help.models import DjangoHelpArticle


logger = logging.getLogger(__name__)


if TYPE_CHECKING:
    from django_help.models import DjangoHelpArticleQuerySet
    from django_help.models import DjangoHelpCategoryQuerySet


[docs]def filter_user_can_view( request: HttpRequest, articles_or_categories: Union[DjangoHelpArticleQuerySet, DjangoHelpCategoryQuerySet] ) -> Union[DjangoHelpArticleQuerySet, DjangoHelpCategoryQuerySet]: """Filters QuerySet to return only public articles or categories based on the user's entity context.""" if request.user.is_staff: return articles_or_categories if request.entity_context.id == request.provider_context.id: return articles_or_categories.intended_for_providers_or_any().public() return articles_or_categories.intended_for_consumers_or_any().public()
[docs]def filter_articles(request: HttpRequest, category: str, slug: str, tag: str) -> DjangoHelpArticleQuerySet: """Filters articles based on user permissions and provided parameters. Note: This is a helper function for get_articles. """ logger.info( "Called get_filtered_articles for: %s, %s, %s, %s, %s, %s", category, type(category), slug, type(slug), tag, request.path, ) articles = filter_user_can_view(request, DjangoHelpArticle.objects.all()) if tag is not None: logger.info("Getting articles for: %s", tag) articles = articles.get_for_tag(unquote(tag), multiple=True) elif slug is not None: logger.info("Getting articles for: %s", slug) articles = articles.get_for_slug(unquote(slug), multiple=True) elif category is not None: logger.info("Getting articles for: %s", category) articles = articles.get_for_category(unquote(category), multiple=True) else: logger.info("Getting articles for: %s", request.path) articles = articles.get_for_path(request.path, multiple=True) if not request.user.is_staff: articles = articles.public() return articles
[docs]def annotate_with_values_fields(queryset, values_fields: list[str]): """Annotates the queryset with the values fields. For instance, if values_fields = ["title"], the queryset will be annotated with `title=to_attribute("title")`, ensuring the current language is used. e.g.: If the currentl language is 'en', the annotation will convert `title_en` to `title`. """ return queryset.annotate(**{field: F(to_attribute(field)) for field in values_fields})