首页 > 解决方案 > 为什么这个 Django 视图在帖子中被执行两次?

问题描述

我有一个 Django 视图,可以通过 Stripe 为用户注册免费试用版。当视图发出 POST 请求时,它会这样做两次。

我已经尝试过幂等键,无论是if request.method == 'POST'在行之后还是在视图的初始渲染中。Stripe 中的客户总是会得到两个相同的付款来源和两个相同的计划订阅。

def start_trial(request):
    title = 'get started'
    description = title
    form = MembershipForm()
    key = settings.STRIPE_PUBLISHABLE_KEY
    trial_days = 30
    coupon = None
    custom_message = ''
    subscription_idempotency = str(uuid.uuid4())
    source_idempotency = str(uuid.uuid4())
    try:
        vendor = Vendor.objects.get(user=request.user)
        custom_message = vendor.message
        coupon = Coupon.objects.get(vendor.coupon)
        coupon = coupon.stripe_coupon_id
        trial_days = vendor.trial_days
    except Vendor.DoesNotExist:
        pass
    try:
        partner = Partner.objects.get(user=request.user)
        custom_message = partner.message
        coupon = Coupon.objects.get(partner.coupon)
        coupon = coupon.stripe_coupon_id
        trial_days = partner.trial_days
    except Partner.DoesNotExist:
        pass
    if request.method == 'POST':
        form = MembershipForm(request.POST)
        if form.is_valid():
            user = request.user
            plan = Membership.objects.get(type_of=form.cleaned_data['plan'])
            # stripe needs to attempt to create a customer
            # TODO what if there's already a membership/subscription?
            user_membership = UserMembership.objects.get(user=request.user)
            stripe_subscription = stripe.Subscription.create(
                customer=user_membership.stripe_customer_id,
                items=[
                    {"plan": plan.stripe_plan_id}
                ],
                trial_period_days=trial_days,
                coupon=coupon,
                idempotency_key=subscription_idempotency,
            )
            subscription = Subscription.objects.create(
                user_membership=user_membership, stripe_subscription_id=stripe_subscription.id)
            subscription.save()
            stripe.Customer.create_source(user_membership.stripe_customer_id,
                                            source=request.POST.get('stripeToken'),
                                            idempotency_key=source_idempotency)
            user_membership.membership = plan
            user_membership.save()
            user.is_subscriber = True
            user.save()

            # if subscription status is incomplete, display error.

            # if passes, redirect to onboarding
            message = 'yay'
            messages.success(request, message=message)
            return HttpResponseRedirect('/onboarding/')
    return render(request, 'memberships/free_trial.html',
                  {'title': title, 'description': description, 'form': form,
                   'key': key, 'custom_message': custom_message})

数据总是在 Stripe 中结束两次。日志显示:

[18/Jun/2019 11:05:21] "POST /memberships/free-trial/ HTTP/1.1" 302 0
[18/Jun/2019 11:05:22] "POST /memberships/free-trial/ HTTP/1.1" 302 0

标签: djangostripe-payments

解决方案


感谢@duck为我指明了正确的方向。我没有看到(对我而言)JavaScript 复制了视图中发生的事情。删除了有问题的文件,问题就解决了。


推荐阅读