Bump Django to 4.1.* (#2989)

This commit is contained in:
Raphael Michel
2023-06-05 09:56:31 +02:00
committed by GitHub
parent 3a8556bb78
commit bd32b33ba9
119 changed files with 742 additions and 613 deletions

View File

@@ -36,6 +36,7 @@
from decimal import Decimal
from urllib.parse import urlencode, urlparse
from zoneinfo import ZoneInfo
from django import forms
from django.conf import settings
@@ -55,7 +56,7 @@ from django_countries.fields import LazyTypedChoiceField
from i18nfield.forms import (
I18nForm, I18nFormField, I18nFormSetMixin, I18nTextarea, I18nTextInput,
)
from pytz import common_timezones, timezone
from pytz import common_timezones
from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
@@ -221,7 +222,7 @@ class EventWizardBasicsForm(I18nModelForm):
})
# change timezone
zone = timezone(data.get('timezone'))
zone = ZoneInfo(data.get('timezone'))
data['date_from'] = self.reset_timezone(zone, data.get('date_from'))
data['date_to'] = self.reset_timezone(zone, data.get('date_to'))
data['presale_start'] = self.reset_timezone(zone, data.get('presale_start'))
@@ -230,7 +231,7 @@ class EventWizardBasicsForm(I18nModelForm):
@staticmethod
def reset_timezone(tz, dt):
return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None
return dt.replace(tzinfo=tz) if dt is not None else None
def clean_slug(self):
slug = self.cleaned_data['slug']

View File

@@ -747,7 +747,7 @@ class ItemVariationsFormSet(I18nFormSet):
def _should_delete_form(self, form):
should_delete = super()._should_delete_form(form)
if should_delete and (form.instance.orderposition_set.exists() or form.instance.cartposition_set.exists()):
if should_delete and form.instance.pk and (form.instance.orderposition_set.exists() or form.instance.cartposition_set.exists()):
form._delete_fail = True
return False
return form.cleaned_data.get(DELETION_FIELD_NAME, False)

View File

@@ -602,7 +602,7 @@ class WebHookForm(forms.ModelForm):
mark_safe('{} <code>{}</code>'.format(a.verbose_name, a.action_type))
) for a in get_all_webhook_events().values()
]
if self.instance:
if self.instance and self.instance.pk:
self.fields['events'].initial = list(self.instance.listeners.values_list('action_type', flat=True))
class Meta:

View File

@@ -19,7 +19,6 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
from bootstrap3.renderers import FieldRenderer, InlineFieldRenderer
from bootstrap3.text import text_value
from django.forms import CheckboxInput
from django.forms.utils import flatatt
@@ -28,6 +27,8 @@ from django.utils.safestring import mark_safe
from django.utils.translation import pgettext
from i18nfield.forms import I18nFormField
from pretix.base.forms.renderers import FieldRenderer, InlineFieldRenderer
def render_label(content, label_for=None, label_class=None, label_title='', optional=False):
"""

View File

@@ -39,7 +39,6 @@ from decimal import Decimal
import bleach
import dateutil.parser
import pytz
from django.dispatch import receiver
from django.urls import reverse
from django.utils.formats import date_format
@@ -209,7 +208,7 @@ def _display_checkin(event, logentry):
if 'datetime' in data:
dt = dateutil.parser.parse(data.get('datetime'))
show_dt = abs((logentry.datetime - dt).total_seconds()) > 5 or 'forced' in data
tz = pytz.timezone(event.settings.timezone)
tz = event.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in data:
@@ -627,7 +626,7 @@ def pretixcontrol_logentry_display(sender: Event, logentry: LogEntry, **kwargs):
if logentry.action_type == 'pretix.control.views.checkin':
# deprecated
dt = dateutil.parser.parse(data.get('datetime'))
tz = pytz.timezone(sender.settings.timezone)
tz = sender.timezone
dt_formatted = date_format(dt.astimezone(tz), "SHORT_DATETIME_FORMAT")
if 'list' in data:
try:

View File

@@ -33,8 +33,7 @@
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from django.conf.urls import re_path
from django.urls import include
from django.urls import include, re_path
from django.views.generic.base import RedirectView
from pretix.control.views import (

View File

@@ -19,18 +19,7 @@
# You should have received a copy of the GNU Affero General Public License along with this program. If not, see
# <https://www.gnu.org/licenses/>.
#
# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of
# the Apache License 2.0 can be obtained at <http://www.apache.org/licenses/LICENSE-2.0>.
#
# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A
# full history of changes and contributors is available at <https://github.com/pretix/pretix>.
#
# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu
#
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
from datetime import timezone
import dateutil.parser
from django.contrib import messages
@@ -44,7 +33,6 @@ from django.utils.functional import cached_property
from django.utils.timezone import is_aware, make_aware, now
from django.utils.translation import gettext_lazy as _
from django.views.generic import ListView
from pytz import UTC
from pretix.base.channels import get_all_sales_channels
from pretix.base.models import Checkin, Order, OrderPosition
@@ -60,6 +48,18 @@ from pretix.control.views import CreateView, PaginationMixin, UpdateView
from pretix.helpers.compat import CompatDeleteView
from pretix.helpers.models import modelcopy
# This file is based on an earlier version of pretix which was released under the Apache License 2.0. The full text of
# the Apache License 2.0 can be obtained at <http://www.apache.org/licenses/LICENSE-2.0>.
#
# This file may have since been changed and any changes are released under the terms of AGPLv3 as described above. A
# full history of changes and contributors is available at <https://github.com/pretix/pretix>.
#
# This file contains Apache-licensed contributions copyrighted by: Jakob Schnell, jasonwaiting@live.hk, pajowu
#
# Unless required by applicable law or agreed to in writing, software distributed under the Apache License 2.0 is
# distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations under the License.
class CheckInListQueryMixin:
@@ -163,20 +163,20 @@ class CheckInListShow(EventPermissionRequiredMixin, PaginationMixin, CheckInList
if e.last_entry:
if isinstance(e.last_entry, str):
# Apparently only happens on SQLite
e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), UTC)
e.last_entry_aware = make_aware(dateutil.parser.parse(e.last_entry), timezone.utc)
elif not is_aware(e.last_entry):
# Apparently only happens on MySQL
e.last_entry_aware = make_aware(e.last_entry, UTC)
e.last_entry_aware = make_aware(e.last_entry, timezone.utc)
else:
# This would be correct, so guess on which database it works… Yes, it's PostgreSQL.
e.last_entry_aware = e.last_entry
if e.last_exit:
if isinstance(e.last_exit, str):
# Apparently only happens on SQLite
e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), UTC)
e.last_exit_aware = make_aware(dateutil.parser.parse(e.last_exit), timezone.utc)
elif not is_aware(e.last_exit):
# Apparently only happens on MySQL
e.last_exit_aware = make_aware(e.last_exit, UTC)
e.last_exit_aware = make_aware(e.last_exit, timezone.utc)
else:
# This would be correct, so guess on which database it works… Yes, it's PostgreSQL.
e.last_exit_aware = e.last_exit

View File

@@ -34,8 +34,8 @@
from datetime import timedelta
from decimal import Decimal
from zoneinfo import ZoneInfo
import pytz
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models import (
@@ -510,7 +510,7 @@ def widgets_for_event_qs(request, qs, user, nmax, lazy=False):
for event in events:
if not lazy:
tzname = event.cache.get_or_set('timezone', lambda: event.settings.timezone)
tz = pytz.timezone(tzname)
tz = ZoneInfo(tzname)
if event.has_subevents:
if event.min_from is None:
dr = pgettext("subevent", "No dates")

View File

@@ -41,6 +41,7 @@ from decimal import Decimal
from io import BytesIO
from itertools import groupby
from urllib.parse import urlsplit
from zoneinfo import ZoneInfo
import bleach
import qrcode
@@ -67,7 +68,6 @@ from django.views.generic.base import TemplateView, View
from django.views.generic.detail import SingleObjectMixin
from i18nfield.strings import LazyI18nString
from i18nfield.utils import I18nJSONEncoder
from pytz import timezone
from pretix.base.channels import get_all_sales_channels
from pretix.base.email import get_available_placeholders
@@ -253,7 +253,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
self.item_meta_property_formset.is_valid() and self.confirm_texts_formset.is_valid() and \
self.footer_links_formset.is_valid():
# reset timezone
zone = timezone(self.sform.cleaned_data['timezone'])
zone = ZoneInfo(self.sform.cleaned_data['timezone'])
event = form.instance
event.date_from = self.reset_timezone(zone, event.date_from)
event.date_to = self.reset_timezone(zone, event.date_to)
@@ -266,7 +266,7 @@ class EventUpdate(DecoupleMixin, EventSettingsViewMixin, EventPermissionRequired
@staticmethod
def reset_timezone(tz, dt):
return tz.localize(dt.replace(tzinfo=None)) if dt is not None else None
return dt.replace(tzinfo=tz) if dt is not None else None
@cached_property
def item_meta_property_formset(self):

View File

@@ -60,8 +60,7 @@ from django.utils.timezone import get_current_timezone, now
from django.utils.translation import gettext, gettext_lazy as _
from django.views import View
from django.views.generic import (
CreateView, DeleteView, DetailView, FormView, ListView, TemplateView,
UpdateView,
CreateView, DetailView, FormView, ListView, TemplateView, UpdateView,
)
from pretix.api.models import ApiCall, WebHook
@@ -1775,7 +1774,7 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
instance = self.scheduled or ScheduledOrganizerExport(
organizer=self.request.organizer,
owner=self.request.user,
timezone=get_current_timezone().zone,
timezone=str(get_current_timezone()),
)
if not self.scheduled:
initial = {
@@ -1811,7 +1810,7 @@ class ExportView(OrganizerPermissionRequiredMixin, ExportMixin, ListView):
return ctx
class DeleteScheduledExportView(OrganizerPermissionRequiredMixin, ExportMixin, DeleteView):
class DeleteScheduledExportView(OrganizerPermissionRequiredMixin, ExportMixin, CompatDeleteView):
template_name = 'pretixcontrol/organizers/export_delete.html'
context_object_name = 'export'

View File

@@ -260,7 +260,7 @@ class SubEventEditorMixin(MetaDataEditorMixin):
form=SimpleCheckinListForm, formset=CheckinListFormSet,
can_order=False, can_delete=True, extra=extra,
)
if self.object:
if self.object and self.object.pk:
kwargs['queryset'] = self.object.checkinlist_set.prefetch_related('limit_products')
return formsetclass(self.request.POST if self.request.method == "POST" else None,
@@ -297,7 +297,7 @@ class SubEventEditorMixin(MetaDataEditorMixin):
form=QuotaForm, formset=QuotaFormSet, min_num=1, validate_min=True,
can_order=False, can_delete=True, extra=extra,
)
if self.object:
if self.object and self.object.pk:
kwargs['queryset'] = self.object.quotas.prefetch_related('items', 'variations')
return formsetclass(
@@ -400,10 +400,10 @@ class SubEventEditorMixin(MetaDataEditorMixin):
def itemvar_forms(self):
se_item_instances = {
sei.item_id: sei for sei in SubEventItem.objects.filter(subevent=self.object)
}
} if self.object and self.object.pk else {}
se_var_instances = {
sei.variation_id: sei for sei in SubEventItemVariation.objects.filter(subevent=self.object)
}
} if self.object and self.object.pk else {}
if self.copy_from:
se_item_instances = {
@@ -821,18 +821,18 @@ class SubEventBulkCreate(SubEventEditorMixin, EventPermissionRequiredMixin, Asyn
for t in self.get_times():
se = copy.copy(form.instance)
se.date_from = make_aware(datetime.combine(rdate, t['time_from']), tz, is_dst=False)
se.date_from = make_aware(datetime.combine(rdate, t['time_from'].replace(fold=1)), tz)
if t.get('time_to'):
se.date_to = (
make_aware(datetime.combine(rdate, t['time_to']), tz, is_dst=False)
make_aware(datetime.combine(rdate, t['time_to'].replace(fold=1)), tz)
if t.get('time_to') > t.get('time_from')
else make_aware(datetime.combine(rdate + timedelta(days=1), t['time_to']), tz, is_dst=False)
else make_aware(datetime.combine(rdate + timedelta(days=1), t['time_to'].replace(fold=1)), tz)
)
else:
se.date_to = None
se.date_admission = (
make_aware(datetime.combine(rdate, t['time_admission'].replace(fold=1)), tz, is_dst=False)
make_aware(datetime.combine(rdate, t['time_admission'].replace(fold=1)), tz)
if t.get('time_admission')
else None
)
@@ -1148,6 +1148,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
subevents = list(self.get_queryset().prefetch_related('checkinlist_set'))
to_save_products = []
to_save_gates = []
to_delete_list_ids = []
for f in self.list_formset.forms:
if self.list_formset._should_delete_form(f) and f in self.list_formset.extra_forms:
@@ -1159,7 +1160,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
log_entries += [
q.log_action(action='pretix.event.checkinlist.deleted', user=self.request.user, save=False),
]
q.delete()
to_delete_list_ids.append(q.pk)
elif f in self.list_formset.extra_forms:
change_data = {k: f.cleaned_data.get(k) for k in f.changed_data}
for se in subevents:
@@ -1198,6 +1199,8 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
CheckinList.limit_products.through.objects.bulk_create(to_save_products)
if to_save_gates:
CheckinList.gates.through.objects.bulk_create(to_save_gates)
if to_delete_list_ids:
CheckinList.objects.filter(id__in=to_delete_list_ids).delete()
def save_quota_formset(self, log_entries):
if not self.quota_formset.has_changed():
@@ -1224,6 +1227,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
if to_delete_quota_ids:
Quota.objects.filter(id__in=to_delete_quota_ids).delete()
to_delete_quota_ids = []
for f in self.quota_formset.forms:
if self.quota_formset._should_delete_form(f) and f in self.quota_formset.extra_forms:
@@ -1245,7 +1249,7 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
'id': q.pk
}, save=False)
]
q.delete()
to_delete_quota_ids.append(q.pk)
elif f in self.quota_formset.extra_forms:
change_data = {k: f.cleaned_data.get(k) for k in f.changed_data}
for se in subevents:
@@ -1288,6 +1292,8 @@ class SubEventBulkEdit(SubEventQueryMixin, EventPermissionRequiredMixin, FormVie
Quota.items.through.objects.bulk_create(to_save_items)
if to_save_variations:
Quota.variations.through.objects.bulk_create(to_save_variations)
if to_delete_quota_ids:
Quota.objects.filter(id__in=to_delete_quota_ids).delete()
def get_context_data(self, **kwargs):
ctx = super().get_context_data(**kwargs)

View File

@@ -33,8 +33,8 @@
# License for the specific language governing permissions and limitations under the License.
from datetime import datetime, time
from zoneinfo import ZoneInfo
import pytz
from dateutil.parser import parse
from django.core.exceptions import PermissionDenied
from django.db.models import F, Max, Min, Q
@@ -88,7 +88,7 @@ def serialize_event(e):
if e.min_from is None:
dr = pgettext('subevent', 'No dates')
else:
tz = pytz.timezone(e.settings.timezone)
tz = ZoneInfo(e.settings.timezone)
dr = _('Series:') + ' ' + daterange(
e.min_from.astimezone(tz),
(e.max_fromto or e.max_to or e.max_from).astimezone(tz)