1

I have a view in which I am attempting to do all of the following:

  • Extend an existing form to have additional fields that do not correspond to a model
  • Check if form data is valid
  • Generate a stripe token and process a charge
  • If that charge is successful, save non cc fields in the form to my local db

I believe my logic is all correct here, and that if a charge is created, then form fields that correspond to my model will be saved to my db, and the user will be shown a success page, or an error page otherwise.

However, when attempting to test, I get the error:

TypeError at /url/linked/to/view
__init__() takes 1 positional argument but 2 were given

In attempting to solve this problem on my own, I came across this question. Based on answers to that question, the short answer seems to be that adding self as first argument to the relevant method should resolve the issue, although it doesn't appear to in this case.

My view:

class payment_order(View):
    def post(self, request):
        card_num = request.POST['card_num']
        exp_month = request.POST['exp_month']
        exp_year = request.POST['exp_year']
        cvc = request.POST['cvc']
        email = request.POST['email']
        cart = Cart(request)

        if request.method == 'POST':
            form = OrderPayForm(request.POST)
            if form.is_valid():

                token = stripe.Token.create(
                  card={
                  "number": card_num,
                  "exp_month": int(exp_month),
                  "exp_year": int(exp_year),
                  "cvc": cvc
                   },
                )

                charge = stripe.Charge.create(
                  amount=cart.item['price'],
                  currency="usd",
                  source=token,
                  description="order for "+ email
                )

                if charge['captured'] == True:
                    order = form.save()
                    for item in cart:
                        OrderItem.objects.create(
                            order=order,
                            product=item['product'],
                            price=item['price'],
                        )
                    return render(request, 'orders/created.html', {'order': order})
                else:
                    form = OrderPayForm()
                    return render(request, 'orders/create.html', {'form': form})

I have not overridden __init__(), and aside from using stripe methods and having a deeper level of nesting than my other views, I don't think I am doing anything unusual. What is causing this error in this instance?

Jake Rankin
  • 714
  • 6
  • 22
  • Isn't there an indentation error in `return` statements? – Paandittya Mar 11 '19 at 20:28
  • @Paandittya I don't believe so, although I just edited my question to ensure I pasted my view as it currently is. I was getting a syntax error previously that was due to indentation issues, but I believe how I have it now to be correct. – Jake Rankin Mar 11 '19 at 20:33

1 Answers1

0

I will remove this answer if someone posts a better solution, but I thought it might help others in case they encounter a similar issue.

Basically, I have solved this by switching from a class based view to a function based view, and changing the logic on the last few lines slightly.

My new view that seems to be working:

def payment_order(request):
    card_num = request.POST.get('card_num', False)
    exp_month = request.POST.get('exp_month', False)
    exp_year = request.POST.get('exp_year ', False)
    cvc = request.POST.get('cvc', False)
    email = request.POST.get('email', False)
    cart = Cart(request)

    if request.method == 'POST':
        form = OrderPayForm(request.POST)
        if form.is_valid():

            token = stripe.Token.create(
              card={
              "number": card_num,
              "exp_month": int(exp_month),
              "exp_year": int(exp_year),
              "cvc": cvc
               },
            )

            charge = stripe.Charge.create(
              amount=cart.item['price'],
              currency="usd",
              source=token,
              description="order for "+ email
            )

            if charge['captured'] == True:
                order = form.save()
                for item in cart:
                    OrderItem.objects.create(
                        order=order,
                        product=item['product'],
                        price=item['price'],
                    )
                return render(request, 'orders/created.html', {'order': order})
    form = OrderPayForm()
    return render(request, 'orders/create.html', {'form': form})
Jake Rankin
  • 714
  • 6
  • 22