diff --git a/district/models.py b/district/models.py index dc83652697d775237d2c811cc9fd63c2e29b841c..584c00bd6ad7ff2efa11ede7617a581659111be8 100644 --- a/district/models.py +++ b/district/models.py @@ -53,7 +53,6 @@ from shared.models import ( ExtendedMetadataPageMixin, FooterMixin, MenuMixin, - SharedArticleTypes, SharedTaggedDistrictArticle, SubpageMixin, ) @@ -538,9 +537,7 @@ class DistrictArticlesPage( def get_context(self, request): context = super().get_context(request) context["articles"] = Paginator( - self.append_all_shared_articles( - SharedArticleTypes.DISTRICT, DistrictArticlePage.objects.child_of(self) - ), + self.append_all_shared_articles(DistrictArticlePage.objects.child_of(self)), self.max_items, ).get_page(request.GET.get("page")) return context @@ -564,7 +561,7 @@ class DistrictArticlesPage( context = super().get_context(request) site_article_ids = self.append_all_shared_articles( - SharedArticleTypes.DISTRICT, DistrictArticlePage.objects.child_of(self) + DistrictArticlePage.objects.child_of(self) ).values_list("id", flat=True) # Naplním "tag" a "article_page_list" parametry @@ -582,7 +579,7 @@ class DistrictArticlesPage( separátně, ale pak by se musel rozpadnout ten try/except na více bloků. """ article_page_qs = self.append_all_shared_articles( - SharedArticleTypes.DISTRICT, DistrictArticlePage.objects + DistrictArticlePage.objects ).filter(id__in=site_article_ids) try: diff --git a/main/models.py b/main/models.py index 6d4d882bd32353d3e5206563aef65f86ae90215b..5d6f9e8b7fd4f6b18451b49d15cbd2b9c5cf4b09 100644 --- a/main/models.py +++ b/main/models.py @@ -35,7 +35,6 @@ from shared.models import ( # MenuMixin, ArticlesMixin, ExtendedMetadataHomePageMixin, ExtendedMetadataPageMixin, - SharedArticleTypes, SharedTaggedMainArticle, SubpageMixin, ) @@ -513,9 +512,9 @@ class MainArticlesPage( def get_all_articles_search_response(self, request): article_paginator = Paginator( - self.append_all_shared_articles( - SharedArticleTypes.MAIN, MainArticlePage.objects - ).search(request.GET["q"]), + self.append_all_shared_articles(MainArticlePage.objects).search( + request.GET["q"] + ), 10, ) article_page = article_paginator.get_page(request.GET.get("page", 1)) @@ -543,7 +542,6 @@ class MainArticlesPage( query = request.GET["q"] article_results = self.append_all_shared_articles( - SharedArticleTypes.MAIN, MainArticlePage.objects, ).search(query)[:11] diff --git a/shared/models.py b/shared/models.py index 187a4be4c0e86467d530540e84807039a38a5272..d1e12c9c934263541b3b5d9b1c6ac4400faf8415 100644 --- a/shared/models.py +++ b/shared/models.py @@ -1,5 +1,5 @@ import logging -from enum import Enum +from functools import reduce from django.apps import apps from django.db import models @@ -63,6 +63,9 @@ class ArticleMixin(models.Model): null=True, verbose_name="obrázek", ) + shared = models.BooleanField( + default=False + ) # hidden field to indicate the article is from another page ### PANELS @@ -258,12 +261,6 @@ class SharedTaggedMainArticle(ItemBase): ) -class SharedArticleTypes(Enum): - DISTRICT = "district" - UNIWEB = "uniweb" - MAIN = "main" - - class ArticlesMixin(models.Model): shared_tags = ParentalManyToManyField( "shared.SharedTag", @@ -274,12 +271,16 @@ class ArticlesMixin(models.Model): content_panels = Page.content_panels + [FieldPanel("shared_tags")] - def append_all_shared_articles( - self, source: SharedArticleTypes | None, previous_query: models.QuerySet | None - ): + def append_all_shared_articles(self, previous_query: models.QuerySet | None): """ To prevent circular deps, we get class models during runtime """ + DistrictArticlesPage = apps.get_model(app_label="district.DistrictArticlesPage") + UniwebArticlesIndexPage = apps.get_model( + app_label="uniweb.UniwebArticlesIndexPage" + ) + MainArticlesPage = apps.get_model(app_label="main.MainArticlesPage") + DistrictArticlePage = apps.get_model(app_label="district.DistrictArticlePage") UniwebArticlePage = apps.get_model(app_label="uniweb.UniwebArticlePage") MainArticlePage = apps.get_model(app_label="main.MainArticlePage") @@ -289,58 +290,50 @@ class ArticlesMixin(models.Model): These values must be in correct order """ - main_fields = { - "union_id": F("id"), - "union_page_ptr_id": F("page_ptr_id"), - "union_perex": F("perex"), - "union_date": F("date"), - "union_author": F("author"), - "union_image_id": F("image_id"), - "union_search_image_id": F("search_image_id"), - "union_content": F("content"), - "union_author_page_id": F("author_page_id"), - "union_region": F("region"), - "union_article_type": F("article_type"), - "union_is_black": F("is_black"), - "union_thumb_image_id": F("search_image_id"), - } + main_meta_fields = MainArticlePage._meta.fields + district_meta_fields = DistrictArticlePage._meta.fields + uniweb_meta_fields = UniwebArticlePage._meta.fields + + fields_reducer = ( + lambda assigned, field: assigned + if field.name is "shared" + else assigned | {f"union_{field.name}": F(field.name)} + ) + setup_fields_order = lambda orderBy, orderFrom: reduce( + lambda orderTo, field: orderTo | {f"{field}": orderFrom[field]}, + orderBy.keys(), + {}, + ) - district_fields = { - "union_id": F("id"), - "union_page_ptr_id": F("page_ptr_id"), - "union_perex": F("perex"), - "union_date": F("date"), - "union_author": F("author"), - "union_image_id": F("image_id"), - "union_search_image_id": F("search_image_id"), - "union_content": F("content"), - "union_author_page_id": F("author_page_id"), - "union_region": Value("", models.CharField()), - "union_article_type": Value(0, models.PositiveSmallIntegerField()), - "union_is_black": F("is_black"), - "union_thumb_image_id": F("thumb_image_id"), + main_fields = reduce(fields_reducer, main_meta_fields, {}) | { + "union_thumb_image": F("search_image"), } - uniweb_fields = { - "union_id": F("id"), - "union_page_ptr_id": F("page_ptr_id"), - "union_perex": F("perex"), - "union_date": F("date"), - "union_author": F("author"), - "union_image_id": F("image_id"), - "union_search_image_id": F("search_image_id"), - "union_content": F("content"), - "union_author_page_id": Value( - None, - output_field=models.ForeignKey( - DistrictArticlePage, blank=True, on_delete=models.SET_NULL + district_fields = setup_fields_order( + main_fields, + reduce(fields_reducer, district_meta_fields, {}) + | { + "union_region": Value("", models.CharField()), + "union_article_type": Value(0, models.PositiveSmallIntegerField()), + }, + ) + + uniweb_fields = setup_fields_order( + main_fields, + reduce(fields_reducer, uniweb_meta_fields, {}) + | { + "union_author_page": Value( + None, + output_field=models.ForeignKey( + DistrictArticlePage, blank=True, on_delete=models.SET_NULL + ), ), - ), - "union_region": Value("", models.CharField()), - "union_article_type": Value(0, models.PositiveSmallIntegerField()), - "union_is_black": Value(False, models.BooleanField()), - "union_thumb_image_id": F("search_image_id"), - } + "union_region": Value("", models.CharField()), + "union_article_type": Value(0, models.PositiveSmallIntegerField()), + "union_is_black": Value(False, models.BooleanField()), + "union_thumb_image": F("search_image"), + }, + ) districtArticleQuery: models.QuerySet = DistrictArticlePage.objects uniwebArticlePageQuery: models.QuerySet = UniwebArticlePage.objects @@ -382,18 +375,19 @@ class ArticlesMixin(models.Model): results = ( main_by_slug.values( - **main_fields, shared=Value(True, output_field=models.BooleanField()) + **main_fields, + union_shared=Value(True, output_field=models.BooleanField()), ) .union( uniweb_by_slug.values( **uniweb_fields, - shared=Value(True, output_field=models.BooleanField()), + union_shared=Value(True, output_field=models.BooleanField()), ) ) .union( district_by_slug.values( **district_fields, - shared=Value(True, output_field=models.BooleanField()), + union_shared=Value(True, output_field=models.BooleanField()), ) ) ) @@ -401,20 +395,20 @@ class ArticlesMixin(models.Model): if previous_query is not None: prepared_query = previous_query.live().specific() - if source is SharedArticleTypes.DISTRICT: + if isinstance(self, DistrictArticlesPage): prepared_query = prepared_query.values( **district_fields, - shared=Value(False, output_field=models.BooleanField()), + union_shared=Value(False, output_field=models.BooleanField()), ) - elif source is SharedArticleTypes.UNIWEB: + elif isinstance(self, UniwebArticlesIndexPage): prepared_query = prepared_query.values( **uniweb_fields, - shared=Value(False, output_field=models.BooleanField()), + union_shared=Value(False, output_field=models.BooleanField()), ) - elif source is SharedArticleTypes.MAIN: + elif isinstance(self, MainArticlesPage): prepared_query = prepared_query.values( **main_fields, - shared=Value(False, output_field=models.BooleanField()), + union_shared=Value(False, output_field=models.BooleanField()), ) results = results.union(prepared_query) @@ -425,60 +419,35 @@ class ArticlesMixin(models.Model): results ) # We MUST eval here since we can't turn values() into concrete class instances in QuerySet after union - if source is SharedArticleTypes.DISTRICT: + assign_to_model = lambda unioned: lambda assignment, field: assignment | { + field.name: unioned[f"union_{field.name}"] + } + + if isinstance(self, DistrictArticlesPage): return list( map( - lambda unioned: DistrictArticlePage( - id=unioned["union_id"], - page_ptr_id=unioned["union_page_ptr_id"], - perex=unioned["union_perex"], - date=unioned["union_date"], - author=unioned["union_author"], - image_id=unioned["union_image_id"], - search_image_id=unioned["union_search_image_id"], - content=unioned["union_content"], - author_page_id=unioned["union_author_page_id"], - is_black=unioned["union_is_black"], - thumb_image_id=unioned["union_thumb_image_id"], + lambda unioned: DistrictArticlePage.objects.create( + **reduce(assign_to_model(unioned), district_meta_fields, {}) ), evaluated, ) ) - if source is SharedArticleTypes.UNIWEB: + if isinstance(self, UniwebArticlesIndexPage): return list( map( lambda unioned: UniwebArticlePage( - id=unioned["union_id"], - page_ptr_id=unioned["union_page_ptr_id"], - perex=unioned["union_perex"], - date=unioned["union_date"], - author=unioned["union_author"], - image_id=unioned["union_image_id"], - search_image_id=unioned["union_search_image_id"], - content=unioned["union_content"], + **reduce(assign_to_model(unioned), uniweb_meta_fields, {}) ), evaluated, ) ) - if source is SharedArticleTypes.MAIN: + if isinstance(self, MainArticlesPage): return list( map( lambda unioned: MainArticlePage( - id=unioned["union_id"], - page_ptr_id=unioned["union_page_ptr_id"], - perex=unioned["union_perex"], - date=unioned["union_date"], - author=unioned["union_author"], - image_id=unioned["union_image_id"], - search_image_id=unioned["union_search_image_id"], - content=unioned["union_content"], - author_page_id=unioned["union_author_page_id"], - region=unioned["union_author_page_id"], - article_type=unioned["union_article_type"], - is_black=unioned["union_is_black"], - thumb_image_id=unioned["union_thumb_image_id"], + **reduce(assign_to_model(unioned), main_meta_fields, {}) ), evaluated, ) diff --git a/uniweb/models.py b/uniweb/models.py index 72bc8b9e8a95cef5ebdeb075f95608f9f73df4df..ad9e2dde58d6c548598429dd86c9d7623204e5ef 100644 --- a/uniweb/models.py +++ b/uniweb/models.py @@ -35,7 +35,6 @@ from shared.models import ( ExtendedMetadataHomePageMixin, ExtendedMetadataPageMixin, FooterMixin, - SharedArticleTypes, SharedTaggedUniwebArticle, SubpageMixin, ) @@ -550,7 +549,7 @@ class UniwebArticlesIndexPage( tag = request.GET.get("tag") articles = self.append_all_shared_articles( - SharedArticleTypes.UNIWEB, UniwebArticlePage.objects.child_of(self) + UniwebArticlePage.objects.child_of(self) ) if tag is not None: