user9252255
user9252255

Reputation:

Django: Redirect doesn't work

The checkout time for my event ticket shop is limited to 15 minutes. I now have the issue, once the 15minutes passed, the "timeout" is actually detected and I see "Ticket reservation is too far in the past." as well as the print out in the console "redirect should work". However, the redirect to return redirect('events:index', organizer=organizer, event=event,) doesn't happen. It's somehow just skipped and checkout_page continues to perform all other actions (which it shouldn't). Do you see what I am doing wrong?

def check_if_reservation_expired(
    request,
    timestamp_of_reservation,
    organizer,
    event
):
    """
    * Calculate the latest possible time where tickets are still reserved.
    * Check that 'created' timestamp of reservation item is not expired.
    * If expired, error message is being generated and redirect occurs.
    """
    latest_time_before_expired = timezone.now() - timedelta(
        minutes=settings.MINUTES_TICKET_RESERVATION
    )
    if timestamp_of_reservation < latest_time_before_expired:
        messages.add_message(
            request,
            messages.ERROR,
            _("Ticket reservation is too far in the past.")
        )
        print("redirect should work")
        return redirect(
            'events:index',
            organizer=organizer,
            event=event,
        )

def checkout_page(request):
    """
    * Check if session and ReservedItem exist.
    * Generate order_item dict for every ReservedItem entry, that belongs
      to order_reference.
    If request.method is 'POST':
        * Check if ticket reservation is still valid.
        * Create entries in models OrderItem, Order & ReservedItem.
    """
    session_order_reference = request.session.get('order_reference')
    if request.session.get('order_reference'):
        reserved_items = ReservedItem.objects.filter(
            order_reference=session_order_reference
        )
        if not reserved_items:
            return redirect('website:index')
    else:
        return redirect('website:index')

    taxes_dict = {}
    total_gross = total_tax_amount = 0
    order_items_list = []
    i = 1  # TODO Marc: Is there a more elegant way?

    for item in reserved_items:
        event = item.ticket.event
        timestamp_of_reservation = item.created
        total_gross += item.subtotal
        order_item = {
            'ticket': item.ticket,
            'ticket_name': item.ticket.name,
            'quantity': item.quantity,
            'subtotal': item.subtotal,
            'type': OrderType.ORDER,
            'ticket_reference': session_order_reference + "-" + str(i),
            'access_key': get_random_string(length=10),
        }
        i += 1
        total_tax_amount += add_tax(
            item=item,
            taxes_dict=taxes_dict,
            order_item=order_item,
        )
        order_items_list.append(dict(order_item))
    total_net = total_gross - total_tax_amount  # TODO Marc: Calculate in add_vat func?

    if request.method == 'POST':
        check_if_reservation_expired(
            request=request,
            timestamp_of_reservation=timestamp_of_reservation,
            organizer=event.organizer.slug,
            event=event.slug,
        )

        billing = BillingForm(request.POST, prefix='billing')
        order = OrderForm(request.POST, prefix='order')
        if order.is_valid() or billing.is_valid():

            # Create new order
            new_order_dict = {
                'total_gross': total_gross,
                'total_tax': total_tax_amount,
                'total_net': total_net,
                'total_gross_converted': total_gross,  # TODO Marc
                'event': event,
                'order_reference': session_order_reference,
                'status': OrderStatus.PENDING,
                'access_key': get_random_string(length=10),
            }

            new_order = order.save(commit=False)
            [setattr(new_order, k, v) for k, v in new_order_dict.items()]
            new_order.save()

            # Create order items
            for item in order_items_list:
                OrderItem.objects.create(order=new_order, **item)

            # Create billing profile
            billing_profile = billing.save(commit=False)
            billing_profile.order = new_order
            billing_profile.save()

            return redirect(
                'orders:order-list',
                order_reference=new_order.order_reference,
                access_key=new_order.access_key,
            )
    else:
        billing = BillingForm(prefix='billing')
        order = OrderForm(prefix='order')

    context = {
        'reserved_items': reserved_items,
        'taxes': taxes_dict,
        'total_net': total_net,
        'total_gross': total_gross,
        'currency': event.currency,
        'order': order,
        'billing': billing,
    }

    return render(request, 'checkout/checkout.html', context)

Upvotes: 2

Views: 84

Answers (2)

NS0
NS0

Reputation: 6096

I think it's because you need to actually return the redirect from the checkout_page view, and not just call a function that will return a redirect. So, try rewriting it in a way where you check if the redirect is necessary, and if so, return it in checkout_page directly.

Upvotes: 0

neverwalkaloner
neverwalkaloner

Reputation: 47354

You are not returning redirection in your view. Should be something like this:

if request.method == 'POST':
    redirection = check_if_reservation_expired(
        request=request,
        timestamp_of_reservation=timestamp_of_reservation,
        organizer=event.organizer.slug,
        event=event.slug,
    )
    if redirection:
        return redirection 

Upvotes: 1

Related Questions