Reputation: 27
I'm developing a web application via Aliexpress API.
but I meet some problems such as my title.
I write my view such as below:
def getToken(request):
appKey = 'test12345'
appSecret ='test3456'
redirectUrl = 'http://127.0.0.1:8000/'
#post to submit the request
postdata=urllib.urlencode({
'grant_type':'authorization_code',
'need_refresh_token':True,
'client_id':appKey,
'client_secret':appSecret,
'redirect_uri':redirectUrl,
'code':request.GET['code'],
})
req = urllib2.Request(
url = 'https://gw.api.alibaba.com/openapi/http/1/system.oauth2/getToken/%s' % appKey ,
data = postdata)
#get access_token
value = eval(urllib2.urlopen(req).read())
#Checking the shop
check = aliexpressToken.objects.filter(user=request.user, aliid=value['aliId'])
if check:
return HttpResponseRedirect("/shop/")
else:
result = aliexpressToken(user=request.user, aliid=value['aliId'], resource_owner=value['resource_owner'], refresh_token=value['refresh_token'], access_token=value['access_token'],shop_name='Aliexpress Trade')
result.save()
#get the id of shop which just is added.
shop = aliexpressToken.objects.get(aliid=value['aliId'], user=request.user.id).id
return HttpResponseRedirect("/shop/%s/edit" % shop)
Models:
class aliexpressToken(models.Model):
"""docstring for aliexpressToken"""
user = models.ForeignKey(User)
aliid = models.CharField(max_length=30)
resource_owner = models.CharField(max_length=30)
refresh_token = models.CharField(max_length=50)
access_token = models.CharField(max_length=50)
shop_name = models.CharField(max_length=50)
shop_color = models.CharField(max_length=30)
shop_image = models.CharField(max_length=30)
create_time = models.DateTimeField(auto_now_add=True)
When I try to test to get access from Aliexpress, it'll remind me that int() argument must be a string or a number, not 'SimpleLazyObject' . what Can i do. Thanks very much Error Traceback like this, it contains more information for me. But I can't analyze what happened.
Traceback:
File "D:\Python27\lib\site-packages\django\core\handlers\base.py" in get_response
115. response = callback(request, *callback_args, **callback_kwargs)
File "D:\Project\blog\aliexpress\views.py" in getToken
108. check = aliexpressToken.objects.filter(user=request.user, aliid=value['aliId'])
File "D:\Python27\lib\site-packages\django\db\models\manager.py" in filter
155. return self.get_query_set().filter(*args, **kwargs)
File "D:\Python27\lib\site-packages\django\db\models\query.py" in filter
655. return self._filter_or_exclude(False, *args, **kwargs)
File "D:\Python27\lib\site-packages\django\db\models\query.py" in _filter_or_exclude
673. clone.query.add_q(Q(*args, **kwargs))
File "D:\Python27\lib\site-packages\django\db\models\sql\query.py" in add_q
1266. can_reuse=used_aliases, force_having=force_having)
File "D:\Python27\lib\site-packages\django\db\models\sql\query.py" in add_filter
1197. connector)
File "D:\Python27\lib\site-packages\django\db\models\sql\where.py" in add
71. value = obj.prepare(lookup_type, value)
File "D:\Python27\lib\site-packages\django\db\models\sql\where.py" in prepare
339. return self.field.get_prep_lookup(lookup_type, value)
File "D:\Python27\lib\site-packages\django\db\models\fields\related.py" in get_prep_lookup
143. return self._pk_trace(value, 'get_prep_lookup', lookup_type)
File "D:\Python27\lib\site-packages\django\db\models\fields\related.py" in _pk_trace
216. v = getattr(field, prep_func)(lookup_type, v, **kwargs)
File "D:\Python27\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_lookup
322. return self.get_prep_value(value)
File "D:\Python27\lib\site-packages\django\db\models\fields\__init__.py" in get_prep_value
555. return int(value)
Exception Type: TypeError at /gettoken/
Exception Value: int() argument must be a string or a number, not 'SimpleLazyObject'
Upvotes: 2
Views: 4723
Reputation: 174662
The main cause of your error is here:
#Checking the shop
check = aliexpressToken.objects.filter(user=request.user, aliid=value['aliId'])
Django creates a wrapper class SimpleLazyObject
and this will return the actual object once you access any property or member of the object.
So to "wake up" the lazy object:
#Checking the shop
check = aliexpressToken.objects.filter(user_pk=request.user.pk, aliid=value['aliId'])
This question has other tricks to waking the object, including this one-liner:
user = request.user._wrapped if hasattr(request.user,'_wrapped') else request.user
check = aliexpressToken.objects.filter(user=user, aliid=value['aliId'])
In addition to the above, all the fields in your model are required; so you need to pass all of them, otherwise your model won't get saved.
You also don't need to retrieve the object again, you can access the id directly:
result = aliexpressToken()
result.user = request.user
result.resource_owner = value['resource_owner']
result.aliid = value['aliId']
result.refresh_token = value['refresh_token']
result.access_token = value['access_token']
result.shop_name = 'Aliexpress Trade'
result.shop_color = ''
result.shop_image = ''
result.save()
shop_id = result.pk
This is also very risky:
#get access_token
value = eval(urllib2.urlopen(req).read())
You should never use eval, and especially never from something that is being received from an external system. If there is ever an error in the feed, you might end up executing code that you don't want.
I assume the library is returning json, you can simply:
import json
value = json.loads(urllib2.urlopen(req).read())
Upvotes: 1
Reputation: 40213
Change user=request.user
to user=request.user.id
:
result = aliexpressToken(user=request.user.id, aliid=value['aliId'], resource_owner=value['resource_owner'], refresh_token=value['refresh_token'], access_token=value['access_token'],shop_name='Aliexpress Trade')
Upvotes: 0
Reputation: 356
user = request.user._wrapped if hasattr(request.user,'_wrapped') else request.user
Upvotes: 3