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)