4

我正在尝试向我的 django tastepie 资源发出请求以更新用户信息。到目前为止,我可以发出 post 请求,但 put 不起作用。

在我的 api.py 我有这个:

class UserResource(ModelResource):
   class Meta:
       queryset = User.objects.all()
       resource_name = 'auth/user'
       fields = ['username', 'email']
       authentication = BasicAuthentication()
       authorization = DjangoAuthorization()
       filtering = {
           "username": ('exact',),
       }

class UserSignUpResource(ModelResource):
   class Meta:
       object_class = User
       resource_name = 'register_user'
       fields = ['username', 'email' , 'password']
       allowed_methods = ['put','post']
       authentication = BasicAuthentication()
       authorization = DjangoAuthorization()
       queryset = User.objects.all()


    def obj_create(self, bundle, request=None, **kwargs):

         bundle = super(UserSignUpResource, self).obj_create(bundle)

为了测试我正在使用这个:

import urllib2, json

def post():

    def basic_authorization(user, password):
       s = user + ":" + password
       return "Basic " + s.encode("base64").rstrip()

    data = json.dumps({'username':'david_000', 'email':'davidupdat@gmail.com',   'password':'xxx','provider':'twitter','extra_data':{'access_token':'xxx','id':'xxx'}})

    req = urllib2.Request("http://192.168.1.114:8080/api/stats/register_user/",
    headers = {"Authorization": basic_authorization("xxx","xxx"),"Content-Type": "application/json"}, data = data)
    req.get_method = lambda:'PUT'
    f = urllib2.urlopen(req)

post()

我收到此错误:

Traceback (most recent call last):
File "test.py", line 18, in <module>
   post()
File "test.py", line 16, in post
   f = urllib2.urlopen(req)
File "/usr/lib/python2.7/urllib2.py", line 126, in urlopen
   return _opener.open(url, data, timeout)
File "/usr/lib/python2.7/urllib2.py", line 406, in open
   response = meth(req, response)
File "/usr/lib/python2.7/urllib2.py", line 519, in http_response
   'http', request, response, code, msg, hdrs)
File "/usr/lib/python2.7/urllib2.py", line 444, in error
   return self._call_chain(*args)
File "/usr/lib/python2.7/urllib2.py", line 378, in _call_chain
   result = func(*args)
File "/usr/lib/python2.7/urllib2.py", line 527, in http_error_default
   raise HTTPError(req.get_full_url(), code, msg, hdrs, fp)
urllib2.HTTPError: HTTP Error 400: BAD REQUEST

更新:

我试试这个,但它给了我同样的错误:

def obj_update(self, bundle, request=None, **kwargs):

    bundle = super(UserSignUpResource, self).obj_update(bundle)

任何的想法?提前致谢!

4

2 回答 2

7

这是因为您正在尝试发出 put 请求,但 put 请求用于更新记录而不是创建新记录。Tastypie 将尝试执行 obj_update 方法,并希望在某个实例上执行。但是您正在向 register_user/ url 发出请求,这显然不是一个对象实例,因此对这个 url 使用 put 请求根本没有意义。PUT 用于更新,而不是创建。

于 2013-05-15T14:38:10.500 回答
3

我只是通过一些修改来解决它。使用 hydrate 方法我可以捕获请求方法(如 put ou post)并处理我的请求。像这样:

class UserResource(ModelResource):
   class Meta:
       queryset = User.objects.all()
       resource_name = 'auth/user'
       fields = ['username', 'email','password','extra_data','provider']
       authentication = BasicAuthentication()
       authorization = DjangoAuthorization()
       filtering = {
            "username": ('exact',),
       }

   def prepend_urls(self):
       return [
           url(r"^(?P<resource_name>%s)/(?P<username>[\w\d_.-]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), name="api_dispatch_detail"),
       ]

   def hydrate(self, bundle):
       request_method=bundle.request.META['REQUEST_METHOD']

       if request_method=='POST':
          #do something if you want
       elif request_method=='PUT':
          #do something if you want
       return bundle

为了测试我已经创建了一个 python 文件:

def basic_authorization(user, password):
    s = user + ":" + password
    return "Basic " + s.encode("base64").rstrip()

url = 'http://192.168.1.114:8080/api/stats/auth/user/david/'
payload = {'username':'david', 'email':'david__@gmail.com', 'password':'xxxx','provider':'twitter','extra_data': {'access_token':'xxxx','id':'xxx'}}
headers = {'content-type': 'application/json'}
r = requests.put(url, data=json.dumps(payload), headers=headers, auth=HTTPBasicAuth('xxx', 'xxx')) 

print r.status_code
print r.history
print r.content

post()

它奏效了!

于 2013-05-16T15:05:34.917 回答