diff --git a/network-api/networkapi/templates/pages/base.html b/network-api/networkapi/templates/pages/base.html index 408e424bd8f..c67fa350a42 100644 --- a/network-api/networkapi/templates/pages/base.html +++ b/network-api/networkapi/templates/pages/base.html @@ -33,7 +33,7 @@ {% block stylesheets %} {% if debug_flag %}{% endif %} - + {% endblock %} diff --git a/network-api/networkapi/wagtailpages/pagemodels/blog/blog_index.py b/network-api/networkapi/wagtailpages/pagemodels/blog/blog_index.py index d572abfdf54..7d2d5ad6848 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/blog/blog_index.py +++ b/network-api/networkapi/wagtailpages/pagemodels/blog/blog_index.py @@ -5,11 +5,15 @@ from wagtail.admin.edit_handlers import PageChooserPanel, InlinePanel from wagtail.contrib.routable_page.models import route -from wagtail.core.models import Orderable as WagtailOrderable, Locale +from wagtail.core.models import Orderable as WagtailOrderable from wagtail_localize.fields import SynchronizedField from modelcluster.fields import ParentalKey -from networkapi.wagtailpages.utils import titlecase, get_locale_from_request +from networkapi.wagtailpages.utils import ( + titlecase, + get_locale_from_request, + get_default_locale, +) from sentry_sdk import capture_exception, push_scope @@ -182,8 +186,8 @@ def filter_entries_for_category(self, entries, context): # helper function to resolve category slugs to actual objects def get_category_object_for_slug(self, category_slug): - DEFAULT_LOCALE = Locale.objects.get(language_code=settings.LANGUAGE_CODE) - DEFAULT_LOCALE_ID = DEFAULT_LOCALE.id + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() + english_categories = BlogPageCategory.objects.filter( locale_id=DEFAULT_LOCALE_ID ) diff --git a/network-api/networkapi/wagtailpages/pagemodels/index.py b/network-api/networkapi/wagtailpages/pagemodels/index.py index 386cf568b6c..79339d2f9b9 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/index.py +++ b/network-api/networkapi/wagtailpages/pagemodels/index.py @@ -10,7 +10,7 @@ from taggit.models import Tag from wagtail.admin.edit_handlers import FieldPanel -from wagtail.core.models import Page, Locale +from wagtail.core.models import Page from wagtail.contrib.routable_page.models import RoutablePageMixin, route from wagtail_localize.fields import SynchronizedField, TranslatableField @@ -21,6 +21,7 @@ set_main_site_nav_information, get_page_tree_information, get_locale_from_request, + get_default_locale, ) @@ -115,8 +116,7 @@ def get_entries(self, context=dict()): Get all child entries, filtered down if required based on the `self.filtered` field being set or not. """ - DEFAULT_LANGUAGE_CODE = settings.LANGUAGE_CODE - DEFAULT_LOCALE = Locale.objects.get(language_code=DEFAULT_LANGUAGE_CODE) + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() if 'request' in context: locale = get_locale_from_request(context['request']) diff --git a/network-api/networkapi/wagtailpages/pagemodels/mixin/snippets.py b/network-api/networkapi/wagtailpages/pagemodels/mixin/snippets.py index e7edc60af0e..c1a95b94e60 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/mixin/snippets.py +++ b/network-api/networkapi/wagtailpages/pagemodels/mixin/snippets.py @@ -1,5 +1,4 @@ -from django.conf import settings -from wagtail.core.models import Locale +from networkapi.wagtailpages.utils import get_default_locale class LocalizedSnippet(): @@ -9,7 +8,8 @@ class LocalizedSnippet(): def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) if self.DEFAULT_LOCALE is None: - self.DEFAULT_LOCALE = Locale.objects.get(language_code=settings.LANGUAGE_CODE) + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() + self.DEFAULT_LOCALE = DEFAULT_LOCALE @property def original(self): diff --git a/network-api/networkapi/wagtailpages/pagemodels/products.py b/network-api/networkapi/wagtailpages/pagemodels/products.py index a6571fce650..705f6b5f828 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/products.py +++ b/network-api/networkapi/wagtailpages/pagemodels/products.py @@ -32,7 +32,12 @@ FoundationMetadataPageMixin ) from networkapi.wagtailpages.templatetags.localization import relocalize_url -from networkapi.wagtailpages.utils import insert_panels_after, get_locale_from_request +from networkapi.wagtailpages.utils import ( + insert_panels_after, + get_default_locale, + get_locale_from_request, + get_original_by_slug +) # TODO: Move this util function from networkapi.buyersguide.utils import get_category_og_image_upload_path @@ -54,7 +59,7 @@ def get_categories_for_locale(language_code): end up with an incomplete category list due to missing locale records. """ DEFAULT_LANGUAGE_CODE = settings.LANGUAGE_CODE - DEFAULT_LOCALE = Locale.objects.get(language_code=DEFAULT_LANGUAGE_CODE) + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() default_locale_list = BuyersGuideProductCategory.objects.filter( hidden=False, @@ -67,7 +72,7 @@ def get_categories_for_locale(language_code): try: actual_locale = Locale.objects.get(language_code=language_code) except Locale.DoesNotExist: - actual_locale = Locale.objects.get(language_code=settings.LANGUAGE_CODE) + actual_locale = Locale.objects.get(language_code=DEFAULT_LANGUAGE_CODE) return [ BuyersGuideProductCategory.objects.filter( @@ -636,14 +641,34 @@ def get_status_for_airtable(self): return "Live" return "Draft" + @property + def original_product(self): + return get_original_by_slug(ProductPage, self.slug) + + def get_or_create_votes(self): + """ + If a page doesn't have a ProductPageVotes objects, create it. + Regardless of whether or not its created, return the parsed votes. + """ + if not self.votes: + votes = ProductPageVotes() + votes.save() + self.votes = votes + self.save() + return self.votes.get_votes() + @property def total_vote_count(self): - return sum(self.get_or_create_votes()) + # Voting only happens on the original product, not "self" + product = self.original_product + return sum(product.get_or_create_votes()) @property def creepiness(self): + # Creepiness is tied to the votes on the original product, not "self" + product = self.original_product try: - average = self.creepiness_value / self.total_vote_count + average = product.creepiness_value / product.total_vote_count except ZeroDivisionError: average = 50 return average @@ -653,13 +678,14 @@ def get_voting_json(self): """ Return a dictionary as a string with the relevant data needed for the frontend: """ - votes = self.votes.get_votes() + product = self.original_product + votes = product.votes.get_votes() data = { 'creepiness': { 'vote_breakdown': {k: v for (k, v) in enumerate(votes)}, - 'average': self.creepiness + 'average': product.creepiness }, - 'total': self.total_vote_count + 'total': product.total_vote_count } return json.dumps(data) @@ -824,18 +850,6 @@ def get_voting_json(self): def product_type(self): return "unknown" - def get_or_create_votes(self): - """ - If a page doesn't have a ProductPageVotes objects, create it. - Regardless of whether or not its created, return the parsed votes. - """ - if not self.votes: - votes = ProductPageVotes() - votes.save() - self.votes = votes - self.save() - return self.votes.get_votes() - def get_context(self, request, *args, **kwargs): context = super().get_context(request, *args, **kwargs) context['product'] = self @@ -861,7 +875,7 @@ def serve(self, request, *args, **kwargs): if data.get("value"): # Product ID and Value can both be zero. It's impossible to get a Page with ID of zero. try: - value = int(data["value"]) # ie. 0 to 100 + value = int(data["value"]) except ValueError: return HttpResponseNotAllowed('Product ID or value is invalid') @@ -869,8 +883,11 @@ def serve(self, request, *args, **kwargs): return HttpResponseNotAllowed('Cannot save vote') try: - product = ProductPage.objects.get(pk=self.id) - # If the product exists but isn't live and the user isn't logged in.. + # Get the english version of this product, as votes should only be recorded + # for the "authoritative" product instance, not specific locale versions. + product = self.original_product + + # 404 if the product exists but isn't live and the user isn't logged in. if (not product.live and not request.user.is_authenticated) or not product: return HttpResponseNotFound("Product does not exist") @@ -1497,8 +1514,7 @@ def categories_page(self, request, slug): locale_id = Locale.objects.get(language_code=language_code).id slug = slugify(slug) - DEFAULT_LOCALE = Locale.objects.get(language_code=settings.LANGUAGE_CODE) - DEFAULT_LOCALE_ID = DEFAULT_LOCALE.id + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() # because we may be working with localized content, and the slug # will always be our english slug, we need to find the english diff --git a/network-api/networkapi/wagtailpages/templates/fragments/buyersguide_item.html b/network-api/networkapi/wagtailpages/templates/fragments/buyersguide_item.html index c046f9a925f..7691618f62d 100644 --- a/network-api/networkapi/wagtailpages/templates/fragments/buyersguide_item.html +++ b/network-api/networkapi/wagtailpages/templates/fragments/buyersguide_item.html @@ -1,6 +1,8 @@ -{% load static i18n wagtailimages_tags localization %} +{% load static i18n wagtailimages_tags l10n localization %} -
+
{% if product.privacy_ding %} " ) return html + inline_code + + +def get_default_locale(): + """ + We defer this logic to a function so that we can call it on demand without + running into "the db is not ready for queries yet" problems. + """ + DEFAULT_LOCALE = Locale.objects.get(language_code=settings.LANGUAGE_CODE) + DEFAULT_LOCALE_ID = DEFAULT_LOCALE.id + return ( + DEFAULT_LOCALE, + DEFAULT_LOCALE_ID, + ) + + +def get_original_by_slug(Model, slug): + (DEFAULT_LOCALE, DEFAULT_LOCALE_ID) = get_default_locale() + return Model.objects.get(slug=slug, locale=DEFAULT_LOCALE_ID)