Hello everyone,
Thank you for reading this !
I am a 3 weeks newbie in django. I occurred a picklingerror when integrating qrcode payment(wechat payment) with django-oscar.
Steps cause the promblem:- Add a product in basket and chose to pay directly;
- Chose payment method;
- Jump to preview page and press the “place order” button on it(which by normally will jump to scan code page which has a qrcode on it);
Error message:it works well before, but since tomorrow it display picklingerror like this:
PicklingError at /zh-cn/checkout/preview/
Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Traceback:
Environment:
Request Method: POST
Request URL: http://xiwen.proxy.qqbrowser.cc:8000/zh-cn/checkout/preview/
Django Version: 1.8.5
Python Version: 2.7.10
Installed Applications:
['django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.admin',
'django.contrib.flatpages',
'django.contrib.staticfiles',
'django.contrib.sitemaps',
'django_extensions',
'debug_toolbar',
'apps.gateway',
'widget_tweaks',
'wcpay',
'oscar',
'oscar.apps.analytics',
'apps.checkout',
'oscar.apps.address',
'oscar.apps.shipping',
'oscar.apps.catalogue',
'oscar.apps.catalogue.reviews',
'oscar.apps.partner',
'oscar.apps.basket',
'oscar.apps.payment',
'oscar.apps.offer',
'oscar.apps.order',
'oscar.apps.customer',
'oscar.apps.promotions',
'oscar.apps.search',
'oscar.apps.voucher',
'oscar.apps.wishlists',
'oscar.apps.dashboard',
'oscar.apps.dashboard.reports',
'oscar.apps.dashboard.users',
'oscar.apps.dashboard.orders',
'oscar.apps.dashboard.promotions',
'oscar.apps.dashboard.catalogue',
'oscar.apps.dashboard.offers',
'oscar.apps.dashboard.partners',
'oscar.apps.dashboard.pages',
'oscar.apps.dashboard.ranges',
'oscar.apps.dashboard.reviews',
'oscar.apps.dashboard.vouchers',
'oscar.apps.dashboard.communications',
'oscar.apps.dashboard.shipping',
'haystack',
'treebeard',
'sorl.thumbnail',
'django_tables2']
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.contrib.flatpages.middleware.FlatpageFallbackMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'oscar.apps.basket.middleware.BasketMiddleware')
Traceback:
File "/Library/Python/2.7/site-packages/django/core/handlers/base.py" in get_response
223. response = middleware_method(request, response)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/middleware.py" in process_response
50. request.session.save()
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/db.py" in save
59. session_data=self.encode(self._get_session(no_load=must_create)),
File "/Library/Python/2.7/site-packages/django/contrib/sessions/backends/base.py" in encode
88. serialized = self.serializer().dumps(session_dict)
File "/Library/Python/2.7/site-packages/django/contrib/sessions/serializers.py" in dumps
15. return pickle.dumps(obj, pickle.HIGHEST_PROTOCOL)
Exception Type: PicklingError at /zh-cn/checkout/preview/
Exception Value: Can't pickle <type 'function'>: attribute lookup __builtin__.function failed
Debug info:i debugged and found this problem is threw from handler/base.py.
By the way, i didn’t remember i have change any code which cause this problem.
try:
# Apply response middleware, regardless of the response
for middleware_method in self._response_middleware:
response = middleware_method(request, response)
# Complain if the response middleware returned None (a common error).
if response is None:
raise ValueError(
"%s.process_response didn't return an "
"HttpResponse object. It returned None instead."
% (middleware_method.__self__.__class__.__name__))
response = self.apply_response_fixes(request, response)
except: # Any exception should be gathered and handled
signals.got_request_exception.send(sender=self.__class__, request=request)
response = self.handle_uncaught_exception(request, resolver, sys.exc_info())
Part of my code:- mysite/app/checkout/views.py
class MultiPaymentDetailsView(RedirectSessionMixin, OscarPaymentDetailsView):
template_name = 'checkout/payment_details.html'
template_name_preview = 'checkout/preview.html'
paymentsource_name={
'WeChatPay':"微信担保",
}
paymentsource_method={
'WeChatPay':WechatpayHandle
}
def get_context_data(self, **kwargs):
context=super(OscarPaymentDetailsView,self).get_context_data(**kwargs)
context['paymethod']=self.paymentsource_name[self.get_paymethod()]
return context
def get(self, request, *args, **kwargs):
if kwargs.get('paymethod'):
self.save_paymethod(kwargs.get('paymethod'))
return HttpResponseRedirect('/checkout/preview')
return super(OscarPaymentDetailsView,self).get(self,request, *args, **kwargs)
def handle_payment(self, order_number, total, **kwargs):
"""
Make submission to scancode
"""
self.set_order_number(order_number)
self.set_info()
paymethod=self.paymentsource_method[self.get_paymethod()]
paymethod(self,order_number, **kwargs)
def WechatpayHandle(paymentview,order_number, **kwargs):
"""
Make submission to Wechat
"""
wechatpaymon=WechatpaySessionMixin(paymentview.checkout_session)
if settings.DEBUG:
base_url = 'http://%s' % paymentview.request.META['HTTP_HOST']
else:
base_url = 'https://%s' % Site.objects.get_current().domain
# 向微信服务器发送统一下单请求|send place order request to weixin server
# notify_url = 'http://8d9ce024.ngrok.io/zh-cn/checkout/wechatpay/respond'
notify_url = "%s%s" % (base_url, reverse("checkout:wcpay:wechat-respond"))
print 'notify_url: ',notify_url
comm = Common_util_pub()
out_trade_no = '{0}{1}{2}'.format('scan','_',int(time.time()))
out_trade_no = '{0}{1}'.format(out_trade_no,comm.createNoncestr(32 - len(out_trade_no)))
unifiedpay = UnifiedOrder_pub()
unifiedpay.setParameter('out_trade_no', out_trade_no)
unifiedpay.setParameter('body', '扫一扫支付')
unifiedpay.setParameter('total_fee', '1')
unifiedpay.setParameter('notify_url', notify_url)
unifiedpay.setParameter('trade_type', 'NATIVE')
unifiedorder = unifiedpay.getPrepayId()
start_pay_url = '/zh-cn/checkout/wechatpay/scancode'
code_url = unifiedorder.get('code_url')
# start_pay_url = '/checkout/wechatpay/scancode'
# rp = requests.post(start_pay_url1, json.dumps(code_url))
# print rp
start_pay_url = start_pay_url + '/?code_url=' + code_url
# wechatpaymon.set_wechatpay()
raise RedirectRequired(start_pay_url)
Reference:https://github.com/amyhoo/django-oscar-alipaya good project which didn’t implement qrcode scan but quite the same way.
Any ideas about this problem or materials about how to develop qrcode payment with django will be grateful !
Thanks!
Xiwen