2

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'
user2831966
  • 27
  • 1
  • 9

3 Answers3

3

user = request.user._wrapped if hasattr(request.user,'_wrapped') else request.user

iamsk
  • 346
  • 5
  • 7
  • Hello iamsk, Thanks for your answer. becuase this is a foreignKey in aliexpressToken table, Request.user need be changed to request.user.id. but if i do that, I'll get a null value. – user2831966 Dec 12 '13 at 04:28
  • There need user not id, because django do the foreignKey job for you. To understand this: http://stackoverflow.com/questions/10506766/django-purpose-of-django-utils-functional-simplelazyobject/10507200#10507200 – iamsk Dec 12 '13 at 05:19
  • Hello iamsk,I have solved it. I add a decorator to validate the status of user. – user2831966 Dec 15 '13 at 06:30
1

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())
Community
  • 1
  • 1
Burhan Khalid
  • 169,990
  • 18
  • 245
  • 284
  • Thanks, I'm busy just now. I wanna check that whether the access_token exists or not. so I must judge it by my database. I'll try your method first. – user2831966 Dec 12 '13 at 08:22
0

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')
Matt Williamson
  • 39,165
  • 10
  • 64
  • 72