You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django Oscar使用过期优惠券后购物车自动清空问题求助

Troubleshooting Django Oscar Basket Emptying on Expired Voucher

Hey there, let's get this sorted out—no need to stress, we'll break this down step by step even without seeing your code. Here's how to debug and fix this issue:

1. First, Pinpoint When the Basket Gets Cleared

The error message comes from the check_basket_is_not_empty method, but the real question is when exactly does the basket lose its items? Since you suspect PaymentDetailsView, add quick logging to track basket item counts through this view.

Add temporary debug logs in your project's PaymentDetailsView (either the default Oscar one or your custom override):

import logging
logger = logging.getLogger(__name__)

class YourPaymentDetailsView(PaymentDetailsView):
    def dispatch(self, request, *args, **kwargs):
        # Log basket state when entering the view
        logger.info(f"Entering PaymentDetailsView: Basket has {request.basket.num_items} items")
        response = super().dispatch(request, *args, **kwargs)
        # Log basket state when leaving the view
        logger.info(f"Leaving PaymentDetailsView: Basket has {request.basket.num_items} items")
        return response

Also, add a log to the Basket model's save method to track changes:

# In your project's basket/models.py (if overriding Oscar's Basket)
from oscar.apps.basket.models import Basket as OscarBasket

class Basket(OscarBasket):
    def save(self, *args, **kwargs):
        logger.info(f"Basket {self.id} saved: {self.num_items} items remaining")
        super().save(*args, **kwargs)

Run your app, reproduce the issue, and check the logs—this will tell you exactly which step is clearing the basket.

2. Check Voucher Removal Signal Handlers

Django Oscar emits a voucher_removed signal when an expired voucher is removed from the basket. It’s possible a custom signal handler in your project is accidentally clearing the basket instead of just removing the voucher.

Search your codebase for signal connections tied to voucher_removed:

from oscar.apps.basket.signals import voucher_removed

def handle_voucher_removed(sender, **kwargs):
    basket = kwargs.get('basket')
    # Look for any line like this—this would clear the entire basket!
    # basket.clear()
voucher_removed.connect(handle_voucher_removed)

If you find a handler that calls basket.clear(), comment that line out and test again. That’s likely the culprit.

3. Audit PaymentDetailsView’s Voucher Handling Logic

If the logs point to the post method of PaymentDetailsView, check for custom logic that modifies the basket after voucher removal. Oscar’s default view shouldn’t delete items when removing an expired voucher, but if your team overridden this view, look for:

  • Calls to basket.clear() or basket.lines.all().delete()
  • Logic that reinitializes the basket instead of updating it
  • Errors in voucher validation that trigger unintended basket resets

A quick temporary fix (until you find the root cause) could be to reload the basket from the database after voucher processing:

def post(self, request, *args, **kwargs):
    # Let Oscar handle the post request normally
    response = super().post(request, *args, **kwargs)
    # Reload the basket to ensure items aren't lost
    if hasattr(request, 'basket'):
        request.basket = self.request.basket.__class__.objects.get(id=request.basket.id)
    return response

4. Verify the check_basket_is_not_empty Trigger

Double-check when this method runs. It’s usually a mixin that runs before the view processes the checkout request. If the basket is already empty when this method runs, the error shows up. The logs from step 1 will tell you if the basket is empty before or after this method executes.

Final Tips for a Quick Win

  • If you can’t find the code immediately, roll back any recent changes to the checkout or voucher logic (if your team uses version control).
  • Use Django’s debug mode to trace the stack trace when the error occurs—this will show you exactly which line of code is leading to the empty basket.

You’ve already narrowed down the problem to PaymentDetailsView, so you’re halfway there. Take it step by step, and you’ll fix this in no time.

内容的提问来源于stack exchange,提问作者Sahil

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 07:37:07