Handle existing cart with empty session in presale views (PRETIXEU-D9Y)

This commit is contained in:
Kara Engelhardt
2026-04-13 11:43:04 +02:00
committed by pajowu
parent 35e1df28d9
commit ba75de7e7d
2 changed files with 24 additions and 6 deletions

View File

@@ -114,8 +114,10 @@ class CartMixin:
return cached_invoice_address(self.request) return cached_invoice_address(self.request)
def get_cart(self, answers=False, queryset=None, order=None, downloads=False, payments=None): def get_cart(self, answers=False, queryset=None, order=None, downloads=False, payments=None):
if not self.request.session.session_key and not order: from pretix.presale.views.cart import get_or_create_cart_id
# The user has not even a session ID yet, so they can't have a cart and we can save a lot of work
if not get_or_create_cart_id(self.request, create=False) and not order:
# The user has no cart, so we can save a lot of work
return { return {
'positions': [], 'positions': [],
# Other keys are not used on non-checkout pages # Other keys are not used on non-checkout pages
@@ -377,9 +379,13 @@ def cart_exists(request):
from pretix.presale.views.cart import get_or_create_cart_id from pretix.presale.views.cart import get_or_create_cart_id
if not hasattr(request, '_cart_cache'): if not hasattr(request, '_cart_cache'):
return CartPosition.objects.filter( cid = get_or_create_cart_id(request, create=False)
cart_id=get_or_create_cart_id(request), event=request.event if cid:
).exists() return CartPosition.objects.filter(
cart_id=cid, event=request.event
).exists()
else:
return False
return bool(request._cart_cache) return bool(request._cart_cache)

View File

@@ -33,7 +33,7 @@ from django.conf import settings
from django.core import mail as djmail from django.core import mail as djmail
from django.core.files.uploadedfile import SimpleUploadedFile from django.core.files.uploadedfile import SimpleUploadedFile
from django.core.signing import dumps from django.core.signing import dumps
from django.test import TestCase, TransactionTestCase from django.test import Client, TestCase, TransactionTestCase
from django.utils.crypto import get_random_string from django.utils.crypto import get_random_string
from django.utils.timezone import now from django.utils.timezone import now
from django_countries.fields import Country from django_countries.fields import Country
@@ -4413,6 +4413,18 @@ class CheckoutTestCase(BaseCheckoutTestCase, TimemachineTestMixin, TestCase):
assert len(djmail.outbox) == 1 assert len(djmail.outbox) == 1
assert any(["Invoice_" in a[0] for a in djmail.outbox[0].attachments]) assert any(["Invoice_" in a[0] for a in djmail.outbox[0].attachments])
def test_checkout_empty_session_valid_cart(self):
client = Client()
with scopes_disabled():
api_cid = "{}@api".format(get_random_string(48))
CartPosition.objects.create(
event=self.event, cart_id=api_cid, item=self.ticket,
price=23, expires=now() + timedelta(minutes=10)
)
response = client.get('/%s/%s/w/1234567890abcdef/checkout/questions/' % (self.orga.slug, self.event.slug), query_params={"take_cart_id": api_cid})
assert '€23.00' in response.content.decode()
class CheckoutTransactionTestCase(BaseCheckoutTestCase, TransactionTestCase): class CheckoutTransactionTestCase(BaseCheckoutTestCase, TransactionTestCase):
def test_order_confirmation_mail_invoice_sent_somewhere_else(self): def test_order_confirmation_mail_invoice_sent_somewhere_else(self):