2013-02-27 82 views
1

全面披露:跨發佈到谷歌Tastypie集團轉換POST與Tastypie PUT

我有一個情況我有限的過被髮送到我的API是什麼控制。基本上有兩個Web服務,我需要能夠接受POST數據。兩者都使用帶有urlencoded數據的簡單POST操作(基本上是基本表單提交)。

關於它的「捲曲」的角度思考它像:

curl --data "id=1&foo=2" http://path/to/api 

我的問題是,我不能用POST更新記錄。所以我需要調整模型資源(我相信),使得如果指定的ID,在POST充當PUT而不是POST。

api.py
class urlencodeSerializer(Serializer): 
    formats = ['json', 'jsonp', 'xml', 'yaml', 'html', 'plist', 'urlencoded'] 
    content_types = { 
     'json': 'application/json', 
     'jsonp': 'text/javascript', 
     'xml': 'application/xml', 
     'yaml': 'text/yaml', 
     'html': 'text/html', 
     'plist': 'application/x-plist', 
     'urlencoded': 'application/x-www-form-urlencoded', 
     } 
    # cheating 
    def to_urlencoded(self,content): 
     pass 
    # this comes from an old patch on github, it was never implemented 
    def from_urlencoded(self, data,options=None): 
     """ handles basic formencoded url posts """ 
     qs = dict((k, v if len(v)>1 else v[0]) 
      for k, v in urlparse.parse_qs(data).iteritems()) 
     return qs 


class FooResource(ModelResource): 
    class Meta: 
     queryset = Foo.objects.all() # "id" = models.AutoField(primary_key=True) 
     resource_name = 'foo' 
     authorization = Authorization() # only temporary, I know. 
     serializer = urlencodeSerializer() 

urls.py
foo_resource = FooResource 

... 
url(r'^api/',include(foo_resource.urls)), 
) 

在Freenode上#tastypie,鬼[],建議我覆蓋由在像模型資源創建函數post_list()所以,但是,我還沒有成功地使用它。

def post_list(self, request, **kwargs): 
    if request.POST.get('id'): 
     return self.put_detail(request,**kwargs) 
    else: 
     return super(YourResource, self).post_list(request,**kwargs) 

不幸的是,這種方法不適合我。我希望更大的社區能夠爲這個問題提供一些指導或解決方案。

注:我不能覆蓋該來自客戶端(按:http://django-tastypie.readthedocs.org/en/latest/resources.html#using-put-delete-patch-in-unsupported-places)頭

+0

我使用的方法obj_create這樣的鏈接 http://stackoverflow.com/questions/10070173/tastypie-obj-create-how-to-use-newly-created-object 和工精細 – 2014-04-22 15:14:02

回答

1

我有用戶創建一個類似的問題,我無法檢查該記錄是否已經存在。我結束了創建如果用戶不存在這種情況後會正常工作,其驗證的自定義驗證方法。如果用戶確實存在,我從驗證方法更新記錄。 api仍然返回400響應,但記錄更新。這感覺有點哈克但...

+0

你能不能給一些示例代碼? – 2013-02-28 20:37:10

0

隨着卡瑟爾的建議我可以利用驗證功能來更新我所需要的記錄。雖然這不會返回有效的代碼......它的工作原理。

from tastypie.validation import Validation 
import string # wrapping in int() doesn't work 

class Validator(Validation): 
    def __init__(self,**kwargs): 
     pass 

    def is_valid(self,bundle,request=None): 
     if string.atoi(bundle.data['id']) in Foo.objects.values_list('id',flat=True): 
       # ... update code here 
     else: 
      return {} 

確保您在ModelResource元指定validation = Validator()

+0

是的,它不會返回一個有效的代碼。你能找到解決方案嗎? – itsji10dra 2017-09-29 19:24:30

+0

它返回失敗,但實際上並沒有失敗。那是我的解決方案。 – 2017-09-29 22:49:55

1
from tastypie.validation import Validation 

class MyValidation(Validation): 

    def is_valid(self, bundle, request=None): 
     errors = {} 
     #if this dict is empty validation passes. 

     my_foo = foo.objects.filter(id=1) 
     if not len(my_foo) == 0: #if object exists  
      foo[0].foo = 'bar' #so existing object updated 
      errors['status'] = 'object updated' #this will be returned in the api response 

     return errors 

    #so errors is empty if object does not exist and validation passes. Otherwise object 
    #updated and response notifies you of this 

class FooResource(ModelResource): 
    class Meta: 
     queryset = Foo.objects.all() # "id" = models.AutoField(primary_key=True) 
     validation = MyValidation()