Braintree Django 异常 "can only concatenate str (not "tuple") 到 str"
Braintree Django Exception "can only concatenate str (not "tuple") to str"
我在 Django 项目中使用 Braintree Drop-in。当我在开发环境 (manage.py runserver) 中使用它时,它工作得很好。但是,当我在弹性 beantalk 上访问相同内容时,我收到错误“只能将 str(而不是“元组”)连接到 str”。以下是我的代码。
extras.py
from django.conf import settings
import braintree
gateway = braintree.BraintreeGateway(
braintree.Configuration(
braintree.Environment.Sandbox,
merchant_id=settings.BT_MERCHANT_ID,
public_key=settings.BT_PUBLIC_KEY,
private_key=settings.BT_PRIVATE_KEY,
)
)
def generate_client_token():
return gateway.client_token.generate()
def transact(options):
return gateway.transaction.sale(options)
def find_transaction(id):
return gateway.transaction.find(id)
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
#from django.conf import settings
from invoices.extras import gateway
@receiver(post_save, sender=User)
def create_phone(sender, instance, created, **kwargs):
if created:
gateway.customer.create({
"first_name": instance.first_name,
"last_name": instance.last_name,
"email": instance.email,
"phone": instance.phone_number,
"id": instance.id,
})
views.py
@login_required()
def customer_invoice_view(request, ticket_id):
ticket = get_object_or_404(Ticket, pk=ticket_id)
customer = ticket.customer
client_token = gateway.client_token.generate({"customer_id": str(customer.id)})
invoice = ticket.invoice
if request.method == 'POST':
result = transact({
'amount': invoice.amount_payable,
'payment_method_nonce': request.POST['payment_method_nonce'],
'options': {
"submit_for_settlement": True
}
})
if result.is_success or result.transaction:
invoice.is_paid = True
invoice.save()
ticket = invoice.ticket
ticket.status ='Payment Made'
ticket.paid = True
ticket.save()
return redirect(customer_invoice_view, ticket_id=ticket.id)
else:
for x in result.errors.deep_errors:
messages.info(request, x)
return redirect(customer_invoice_view, ticket_id=ticket.id)
context = {
'ticket' : ticket,
'invoice' : invoice,
'client_token' : client_token,
}
return render(request, 'invoice/ticket_invoice_view.html', context)
ticket_invoice_view.html
<div class="p-3">
{% if not invoice.is_paid%}
<div class="row no-gutters">
<div class="mb-2">
<ul>
{% for message in messages %}
<li class="text-dark">{{message}}</li>
{% endfor %}
</ul>
</div>
</div>
<div class="row no-gutters my-4">
<form id="payment-form" method="post" action="" autocomplete="off">
{% csrf_token %}
<section>
<div class="bt-drop-in-wrapper">
<div id="bt-dropin"></div>
</div>
</section>
<input type="hidden" id="nonce" name="payment_method_nonce" />
<button class="btn-success" type="submit" id="submit-button"><span>Make Payment</span></button>
</form>
</div>
{% endif %}
</div>
<script src="https://js.braintreegateway.com/web/dropin/1.25.0/js/dropin.min.js"></script>
<script>
var form = document.querySelector('#payment-form');
var client_token = '{{ client_token }}';
braintree.dropin.create({
authorization: client_token,
container: '#bt-dropin',
paypal: {
flow: 'vault'
}
}, function (createErr, instance) {
form.addEventListener('submit', function (event) {
event.preventDefault();
instance.requestPaymentMethod(function (err, payload) {
if (err) {
console.log('Error', err);
return;
}
// Add the nonce to the form and submit
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
});
});
</script>
当我在本地 运行 项目(manage.py 运行服务器)时,它工作正常,当创建用户时,会在 Braintree 中创建一个客户,其用户 ID 作为客户 ID。并且付款也得到了处理,没有任何问题。但是当通过弹性 beantalk 完成相同操作时,我收到错误“只能将 str(不是“元组”)连接到 str”。
回溯如下
TypeError: can only concatenate str (not "tuple") to str
File "django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "accounts/decorators.py", line 20, in wrapper_func
return view_func(request, *args, **kwargs)
File "invoices/views.py", line 33, in customer_invoice_view
client_token = gateway.client_token.generate({"customer_id": str(customer.id),},)
File "braintree/client_token_gateway.py", line 26, in generate
response = self.config.http().post(self.config.base_merchant_path() + "/client_token", params)
File "braintree/configuration.py", line 113, in base_merchant_path
return "/merchants/" + self.merchant_id
这是 Post 保存信号错误的回溯。
TypeError: can only concatenate str (not "tuple") to str
File "django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "django/views/decorators/debug.py", line 89, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "allauth/account/views.py", line 230, in dispatch
return super(SignupView, self).dispatch(request, *args, **kwargs)
File "allauth/account/views.py", line 75, in dispatch
request, *args, **kwargs
File "allauth/account/views.py", line 204, in dispatch
return super(CloseableSignupMixin, self).dispatch(request, *args, **kwargs)
File "django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "allauth/account/views.py", line 102, in post
response = self.form_valid(form)
File "allauth/account/views.py", line 246, in form_valid
self.user = form.save(self.request)
File "allauth/account/forms.py", line 419, in save
adapter.save_user(request, user, self)
File "allauth/account/adapter.py", line 246, in save_user
user.save()
File "django/contrib/auth/base_user.py", line 67, in save
super().save(*args, **kwargs)
File "django/db/models/base.py", line 754, in save
force_update=force_update, update_fields=update_fields)
File "django/db/models/base.py", line 803, in save_base
update_fields=update_fields, raw=raw, using=using,
File "django/dispatch/dispatcher.py", line 179, in send
for receiver in self._live_receivers(sender)
File "django/dispatch/dispatcher.py", line 179, in <listcomp>
for receiver in self._live_receivers(sender)
File "accounts/signals.py", line 30, in create_phone
"id": instance.id,
File "braintree/customer_gateway.py", line 24, in create
return self._post("/customers", {"customer": params})
File "braintree/customer_gateway.py", line 79, in _post
response = self.config.http().post(self.config.base_merchant_path() + url, params)
File "braintree/configuration.py", line 113, in base_merchant_path
return "/merchants/" + self.merchant_id
如果有人能帮我解决,我将不胜感激
感谢您的详细问题!
错误就是线索。它说您正在尝试连接不允许的元组和字符串。由于该行是 return "/merchants/" + self.merchant_id
并且我没有看到表示无关元组的逗号,这意味着问题出在 self.merchant_id
上。这似乎是从 settings.BT_MERCHANT_ID
开始设置的。我的直觉是 settings.BT_MERCHANT_ID
在它的末尾有一个逗号,而它不应该导致它成为一个元组。
例如:
x = 1
导致 x
被设置为整数 1
。但是
x = 1,
导致 x
被设置为元组 (1, )
。这是一个痛苦的陷阱,最终困扰着每个 python 开发人员。
我在 Django 项目中使用 Braintree Drop-in。当我在开发环境 (manage.py runserver) 中使用它时,它工作得很好。但是,当我在弹性 beantalk 上访问相同内容时,我收到错误“只能将 str(而不是“元组”)连接到 str”。以下是我的代码。
extras.py
from django.conf import settings
import braintree
gateway = braintree.BraintreeGateway(
braintree.Configuration(
braintree.Environment.Sandbox,
merchant_id=settings.BT_MERCHANT_ID,
public_key=settings.BT_PUBLIC_KEY,
private_key=settings.BT_PRIVATE_KEY,
)
)
def generate_client_token():
return gateway.client_token.generate()
def transact(options):
return gateway.transaction.sale(options)
def find_transaction(id):
return gateway.transaction.find(id)
signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver
#from django.conf import settings
from invoices.extras import gateway
@receiver(post_save, sender=User)
def create_phone(sender, instance, created, **kwargs):
if created:
gateway.customer.create({
"first_name": instance.first_name,
"last_name": instance.last_name,
"email": instance.email,
"phone": instance.phone_number,
"id": instance.id,
})
views.py
@login_required()
def customer_invoice_view(request, ticket_id):
ticket = get_object_or_404(Ticket, pk=ticket_id)
customer = ticket.customer
client_token = gateway.client_token.generate({"customer_id": str(customer.id)})
invoice = ticket.invoice
if request.method == 'POST':
result = transact({
'amount': invoice.amount_payable,
'payment_method_nonce': request.POST['payment_method_nonce'],
'options': {
"submit_for_settlement": True
}
})
if result.is_success or result.transaction:
invoice.is_paid = True
invoice.save()
ticket = invoice.ticket
ticket.status ='Payment Made'
ticket.paid = True
ticket.save()
return redirect(customer_invoice_view, ticket_id=ticket.id)
else:
for x in result.errors.deep_errors:
messages.info(request, x)
return redirect(customer_invoice_view, ticket_id=ticket.id)
context = {
'ticket' : ticket,
'invoice' : invoice,
'client_token' : client_token,
}
return render(request, 'invoice/ticket_invoice_view.html', context)
ticket_invoice_view.html
<div class="p-3">
{% if not invoice.is_paid%}
<div class="row no-gutters">
<div class="mb-2">
<ul>
{% for message in messages %}
<li class="text-dark">{{message}}</li>
{% endfor %}
</ul>
</div>
</div>
<div class="row no-gutters my-4">
<form id="payment-form" method="post" action="" autocomplete="off">
{% csrf_token %}
<section>
<div class="bt-drop-in-wrapper">
<div id="bt-dropin"></div>
</div>
</section>
<input type="hidden" id="nonce" name="payment_method_nonce" />
<button class="btn-success" type="submit" id="submit-button"><span>Make Payment</span></button>
</form>
</div>
{% endif %}
</div>
<script src="https://js.braintreegateway.com/web/dropin/1.25.0/js/dropin.min.js"></script>
<script>
var form = document.querySelector('#payment-form');
var client_token = '{{ client_token }}';
braintree.dropin.create({
authorization: client_token,
container: '#bt-dropin',
paypal: {
flow: 'vault'
}
}, function (createErr, instance) {
form.addEventListener('submit', function (event) {
event.preventDefault();
instance.requestPaymentMethod(function (err, payload) {
if (err) {
console.log('Error', err);
return;
}
// Add the nonce to the form and submit
document.querySelector('#nonce').value = payload.nonce;
form.submit();
});
});
});
</script>
当我在本地 运行 项目(manage.py 运行服务器)时,它工作正常,当创建用户时,会在 Braintree 中创建一个客户,其用户 ID 作为客户 ID。并且付款也得到了处理,没有任何问题。但是当通过弹性 beantalk 完成相同操作时,我收到错误“只能将 str(不是“元组”)连接到 str”。
回溯如下
TypeError: can only concatenate str (not "tuple") to str
File "django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "django/contrib/auth/decorators.py", line 21, in _wrapped_view
return view_func(request, *args, **kwargs)
File "accounts/decorators.py", line 20, in wrapper_func
return view_func(request, *args, **kwargs)
File "invoices/views.py", line 33, in customer_invoice_view
client_token = gateway.client_token.generate({"customer_id": str(customer.id),},)
File "braintree/client_token_gateway.py", line 26, in generate
response = self.config.http().post(self.config.base_merchant_path() + "/client_token", params)
File "braintree/configuration.py", line 113, in base_merchant_path
return "/merchants/" + self.merchant_id
这是 Post 保存信号错误的回溯。
TypeError: can only concatenate str (not "tuple") to str
File "django/core/handlers/exception.py", line 47, in inner
response = get_response(request)
File "django/core/handlers/base.py", line 179, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "django/views/generic/base.py", line 70, in view
return self.dispatch(request, *args, **kwargs)
File "django/utils/decorators.py", line 43, in _wrapper
return bound_method(*args, **kwargs)
File "django/views/decorators/debug.py", line 89, in sensitive_post_parameters_wrapper
return view(request, *args, **kwargs)
File "allauth/account/views.py", line 230, in dispatch
return super(SignupView, self).dispatch(request, *args, **kwargs)
File "allauth/account/views.py", line 75, in dispatch
request, *args, **kwargs
File "allauth/account/views.py", line 204, in dispatch
return super(CloseableSignupMixin, self).dispatch(request, *args, **kwargs)
File "django/views/generic/base.py", line 98, in dispatch
return handler(request, *args, **kwargs)
File "allauth/account/views.py", line 102, in post
response = self.form_valid(form)
File "allauth/account/views.py", line 246, in form_valid
self.user = form.save(self.request)
File "allauth/account/forms.py", line 419, in save
adapter.save_user(request, user, self)
File "allauth/account/adapter.py", line 246, in save_user
user.save()
File "django/contrib/auth/base_user.py", line 67, in save
super().save(*args, **kwargs)
File "django/db/models/base.py", line 754, in save
force_update=force_update, update_fields=update_fields)
File "django/db/models/base.py", line 803, in save_base
update_fields=update_fields, raw=raw, using=using,
File "django/dispatch/dispatcher.py", line 179, in send
for receiver in self._live_receivers(sender)
File "django/dispatch/dispatcher.py", line 179, in <listcomp>
for receiver in self._live_receivers(sender)
File "accounts/signals.py", line 30, in create_phone
"id": instance.id,
File "braintree/customer_gateway.py", line 24, in create
return self._post("/customers", {"customer": params})
File "braintree/customer_gateway.py", line 79, in _post
response = self.config.http().post(self.config.base_merchant_path() + url, params)
File "braintree/configuration.py", line 113, in base_merchant_path
return "/merchants/" + self.merchant_id
如果有人能帮我解决,我将不胜感激
感谢您的详细问题!
错误就是线索。它说您正在尝试连接不允许的元组和字符串。由于该行是 return "/merchants/" + self.merchant_id
并且我没有看到表示无关元组的逗号,这意味着问题出在 self.merchant_id
上。这似乎是从 settings.BT_MERCHANT_ID
开始设置的。我的直觉是 settings.BT_MERCHANT_ID
在它的末尾有一个逗号,而它不应该导致它成为一个元组。
例如:
x = 1
导致 x
被设置为整数 1
。但是
x = 1,
导致 x
被设置为元组 (1, )
。这是一个痛苦的陷阱,最终困扰着每个 python 开发人员。