Cache sorting of countries

This commit is contained in:
Raphael Michel
2020-04-17 13:21:13 +02:00
parent e70f593a94
commit b6d2f67c7c
3 changed files with 41 additions and 3 deletions

View File

@@ -41,6 +41,7 @@ from pretix.base.settings import (
) )
from pretix.base.templatetags.rich_text import rich_text from pretix.base.templatetags.rich_text import rich_text
from pretix.control.forms import SplitDateTimeField from pretix.control.forms import SplitDateTimeField
from pretix.helpers.countries import CachedCountries
from pretix.helpers.escapejson import escapejson_attr from pretix.helpers.escapejson import escapejson_attr
from pretix.helpers.i18n import get_format_without_seconds from pretix.helpers.i18n import get_format_without_seconds
from pretix.presale.signals import question_form_fields from pretix.presale.signals import question_form_fields
@@ -297,7 +298,9 @@ class BaseQuestionsForm(forms.Form):
}), }),
) )
country = (cartpos.country if cartpos else orderpos.country) or guess_country(event) country = (cartpos.country if cartpos else orderpos.country) or guess_country(event)
self.fields['country'] = CountryField().formfield( self.fields['country'] = CountryField(
countries=CachedCountries
).formfield(
required=event.settings.attendee_addresses_required and not self.all_optional, required=event.settings.attendee_addresses_required and not self.all_optional,
label=_('Country'), label=_('Country'),
initial=country, initial=country,
@@ -380,7 +383,9 @@ class BaseQuestionsForm(forms.Form):
initial=initial.answer if initial else None, initial=initial.answer if initial else None,
) )
elif q.type == Question.TYPE_COUNTRYCODE: elif q.type == Question.TYPE_COUNTRYCODE:
field = CountryField().formfield( field = CountryField(
countries=CachedCountries
).formfield(
label=label, required=required, label=label, required=required,
help_text=help_text, help_text=help_text,
widget=forms.Select, widget=forms.Select,
@@ -575,6 +580,8 @@ class BaseInvoiceAddressForm(forms.ModelForm):
if not event.settings.invoice_address_vatid: if not event.settings.invoice_address_vatid:
del self.fields['vat_id'] del self.fields['vat_id']
self.fields['country'].choices = CachedCountries()
c = [('', pgettext_lazy('address', 'Select state'))] c = [('', pgettext_lazy('address', 'Select state'))]
fprefix = self.prefix + '-' if self.prefix else '' fprefix = self.prefix + '-' if self.prefix else ''
cc = None cc = None

View File

@@ -44,6 +44,7 @@ from pretix.base.services.locking import NoLockManager
from pretix.base.settings import PERSON_NAME_SCHEMES from pretix.base.settings import PERSON_NAME_SCHEMES
from pretix.base.signals import order_gracefully_delete from pretix.base.signals import order_gracefully_delete
from ...helpers.countries import CachedCountries
from .base import LockModel, LoggedModel from .base import LockModel, LoggedModel
from .event import Event, SubEvent from .event import Event, SubEvent
from .items import Item, ItemVariation, Question, QuestionOption, Quota from .items import Item, ItemVariation, Question, QuestionOption, Quota
@@ -2113,7 +2114,8 @@ class InvoiceAddress(models.Model):
zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False) zipcode = models.CharField(max_length=30, verbose_name=_('ZIP code'), blank=False)
city = models.CharField(max_length=255, verbose_name=_('City'), blank=False) city = models.CharField(max_length=255, verbose_name=_('City'), blank=False)
country_old = models.CharField(max_length=255, verbose_name=_('Country'), blank=False) country_old = models.CharField(max_length=255, verbose_name=_('Country'), blank=False)
country = CountryField(verbose_name=_('Country'), blank=False, blank_label=_('Select country')) country = CountryField(verbose_name=_('Country'), blank=False, blank_label=_('Select country'),
countries=CachedCountries)
state = models.CharField(max_length=255, verbose_name=pgettext_lazy('address', 'State'), blank=True) state = models.CharField(max_length=255, verbose_name=pgettext_lazy('address', 'State'), blank=True)
vat_id = models.CharField(max_length=255, blank=True, verbose_name=_('VAT ID'), vat_id = models.CharField(max_length=255, blank=True, verbose_name=_('VAT ID'),
help_text=_('Only for business customers within the EU.')) help_text=_('Only for business customers within the EU.'))

View File

@@ -0,0 +1,29 @@
from django.core.cache import cache
from django.utils.translation import get_language
from django_countries import Countries
class CachedCountries(Countries):
_cached_lists = {}
def __iter__(self):
"""
Iterate through countries, sorted by name, but cache the results based on the locale.
django-countries performs a unicode-aware sorting based on pyuca which is incredibly
slow.
"""
cache_key = "countries:all:{}".format(get_language())
if cache_key in self._cached_lists:
yield from self._cached_lists[cache_key]
return
val = cache.get(cache_key)
if val:
self._cached_lists[cache_key] = val
yield from val
return
val = list(super().__iter__())
self._cached_lists[cache_key] = val
cache.set(cache_key, val, 3600 * 24 * 30)
yield from val