Skip to content
Snippets Groups Projects
Verified Commit b354d13e authored by jindra12's avatar jindra12
Browse files

Start fixing paginator queries

parent 703f372f
No related branches found
No related tags found
2 merge requests!816Release,!801Prepare basic shared tags
......@@ -56,7 +56,7 @@ class LatestArticlesFeed(Feed):
return ""
def item_categories(self, item: MainArticlePage) -> list:
return item.get_tags() if callable(item.get_tags) else item.get_tags
return item.get_tags
def item_link(self, item: MainArticlePage) -> str:
return item.get_full_url
......
......@@ -8,7 +8,7 @@ from django.apps import apps
from django.core.paginator import Paginator
from django.db import models
from django.db.models import Q
from django.db.models.expressions import F, Value
from django.db.models.expressions import F, Subquery, Value
from django.utils import timezone
from modelcluster.fields import ParentalKey, ParentalManyToManyField
from taggit.models import ItemBase, Tag, TagBase
......@@ -69,16 +69,22 @@ class ArticleMixin(models.Model):
null=True,
verbose_name="obrázek",
)
shared_type = models.TextField(
null=True, blank=True
) # hidden field describing the source of shared articles
"""
Hidden field describing the source of shared articles, can be of values "district", "uniweb" or "main",
depending on from which type of site this article was shared from
"""
shared_type = models.TextField(null=True, blank=True)
"""
Hidden field which links to a Page model of ArticlesMixin page to which this article was shared.
Example: DistrictArticlesPage has shared tag "main", which this article shares as well -> shared_from will contain a reference to DistrictArticlesPage
"""
shared_from = models.ForeignKey(
Page,
null=True,
blank=True,
related_name="+",
on_delete=models.PROTECT,
) # hidden field to indicate the article is from another page
)
search_fields = Page.search_fields + [
index.SearchField("title"),
......@@ -109,7 +115,7 @@ class ArticleMixin(models.Model):
@property
def get_no_index(self):
"""
Indicates that a link should contain rel="noindex"
Indicates that a link to self should contain rel="noindex"
"""
return self.shared_from is not None
......@@ -134,6 +140,9 @@ class ArticleMixin(models.Model):
@property
def articles_page(self):
"""
Returns articles page on which this article is displayed
"""
return (
self.shared_from.get_specific()
if self.shared_from
......@@ -142,6 +151,9 @@ class ArticleMixin(models.Model):
@property
def root_page(self):
"""
Returns root page of article, or a root page of Articles page to which this article was shared
"""
if self.shared_from is None:
return self.get_parent().get_ancestors().specific().live().last()
......@@ -149,9 +161,12 @@ class ArticleMixin(models.Model):
@property
def get_tags(self):
"""
Returns all tags, including tags of shared articles from another site
"""
if self.shared_from is not None:
return self.articles_page.search_tags_by_unioned_id_query([self])
return self.tags.all
return self.tags.all()
@classmethod
def has_tags(cls):
......@@ -394,17 +409,27 @@ class ArticlesMixin(models.Model):
).values()
)
def create_base_shared_query(self, query):
def create_base_shared_query(self, query, original_query):
"""
Returns a query filtered by shared tags
Returns a query filtered by shared tags,
Filters out page ids that would be duplicates of original query (shared articles dispayed on the same page)
"""
return (
filtered_query = (
query.filter(
shared_tags__slug__in=self.shared_tags.values_list("slug", flat=True)
~Q(page_ptr_id__in=Subquery(original_query.values("page_ptr_id"))),
shared_tags__slug__in=self.shared_tags.values_list("slug", flat=True),
)
.live()
.specific()
if isinstance(original_query, models.QuerySet)
else query.filter(
~Q(
page_ptr_id__in=list(
map(lambda article: article.pk, original_query)
)
),
shared_tags__slug__in=self.shared_tags.values_list("slug", flat=True),
)
)
return filtered_query.live().specific()
def append_all_shared_articles_query(
self,
......@@ -525,7 +550,7 @@ class ArticlesMixin(models.Model):
)
create_query_by_slug = lambda query: apply_additional_filter(
self.create_base_shared_query(query)
self.create_base_shared_query(query, previous_query)
)
district_by_slug = create_query_by_slug(district_article_query)
......@@ -663,14 +688,17 @@ class ArticlesMixin(models.Model):
self, query: models.QuerySet, page_size: int, page: int
):
"""
Returns a list based on articles query using Paginator internally.
Returns Page object whose property object_list has been materialized, uses Paginator internally
"""
return self.materialize_shared_articles_query(
Paginator(
paginator = Paginator(
query,
page_size,
).get_page(page)
)
paginator_page = paginator.get_page(page)
paginator_page.object_list = self.materialize_shared_articles_query(
paginator_page.object_list
)
return paginator_page
def get_article_page_by_slug(self, slug: str):
"""
......@@ -794,13 +822,13 @@ class ArticlesMixin(models.Model):
)
current_query = search_factory(previous_query)
shared_district_search = search_factory(
self.create_base_shared_query(DistrictArticlePage.objects)
self.create_base_shared_query(DistrictArticlePage.objects, current_query)
)
shared_uniweb_search = search_factory(
self.create_base_shared_query(UniwebArticlePage.objects)
self.create_base_shared_query(UniwebArticlePage.objects, current_query)
)
shared_main_search = search_factory(
self.create_base_shared_query(MainArticlePage.objects)
self.create_base_shared_query(MainArticlePage.objects, current_query)
)
# .search is not lazy either, making this the best optimized query possible AFAIK
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment