2013-01-08 30 views
0

嗨,我使用tastypie暴露在一個項目一個REST API,並就死在如何實現資源的終點,所以這裏是我的問題:如何在單個POST上創建模型資源和相關的多對多資源?

我有以下型號,

class Product(models.Model): 
    # fields... 

class Order(models.Model): 
    products = models.ManyToManyField('Product', through='OrderProduct') 
    # other fields... 

class OrderProduct(models.Model): 
    order  = models.ForeignKey('Order') 
    product = models.ForeignKey('Product') 
    quantity = models.IntegerField() 
    unit_price = models.FloatField() 

    class Meta: 
     unique_together = ['order', 'product'] 

和下面的資源,

class ProductResource(ModelResource): 
    class Meta: 
     resource_name = 'products' 
     queryset = Product.objects.all() 
     allowed_methods = ['get'] 

class OrderResource(ModelResource): 
    products = fields.ToManyField('agro.api.OrderProductResource', 'orderproduct_set', related_name='product', full=True) 

    class Meta: 
     resource_name = 'orders' 
     queryset = Order.objects.all() 
     list_allowed_methods = ['get', 'post'] 
     detail_allowed_methods = ['get', 'put', 'delete'] 
     authentication = Authentication() # only for testing purposes 
     authorization = Authorization() # only for testing purposes 

    class OrderProductResource(ModelResource): 
     product = fields.ForeignKey('agro.api.ProductResource', 'product') 

     class Meta: 
      resource_name = 'orderproducts' 
      queryset = OrderProduct.objects.all() 
      allowed_methods = ['get'] 
      include_resource_uri = False 
      authentication = Authentication() # only for testing purposes 
      authorization = Authorization() # only for testing purposes 

當我嘗試POST到/命令/端點與以下請求數據

{ 
    "products": [ 
     { 
      "product": "/products/1/", 
      "quantity": 4, 
      "unit_price": 5 
     } 
    ] 
} 

我碰到下面的錯誤回溯

{ 
    "error_message": "orderproduct.order_id may not be NULL", 
    "traceback": "Traceback (most recent call last):\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 192, in wrapper\n response = callback(request, *args, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 397, in dispatch_list\n return self.dispatch('list', request, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 427, in dispatch\n response = method(request, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1165, in post_list\n updated_bundle = self.obj_create(bundle, request=request, **self.remove_api_resource_names(kwargs))\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1784, in obj_create\n self.save_m2m(m2m_bundle)\n\n File \"c:\\Python27\\lib\\site-packages\\tastypie\\resources.py\", line 1951, in save_m2m\n related_bundle.obj.save()\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\base.py\", line 463, in save\n self.save_base(using=using, force_insert=force_insert, force_update=force_update)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\base.py\", line 551, in save_base\n result = manager._insert([self], fields=fields, return_id=update_pk, using=using, raw=raw)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\manager.py\", line 203, in _insert\n return insert_query(self.model, objs, fields, **kwargs)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\query.py\", line 1593, in insert_query\n return query.get_compiler(using=using).execute_sql(return_id)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\models\\sql\\compiler.py\", line 912, in execute_sql\n cursor.execute(sql, params)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\backends\\util.py\", line 40, in execute\n return self.cursor.execute(sql, params)\n\n File \"c:\\Python27\\lib\\site-packages\\django\\db\\backends\\sqlite3\\base.py\", line 344, in execute\n return Database.Cursor.execute(self, query, params)\n\nIntegrityError: orderproduct.order_id may not be NULL\n" 
} 

,你可以看到我沒有指定的順序至極新OrderProduct應該涉及到,我試圖做到的,是張貼的訂單資源與它的嵌套OrderProduct數據是在相同的POST請求上創建的。

這裏來了我的問題我如何指定orderProduct引用的順序應該是當前創建的順序,最常用的方法是什麼,覆蓋水合物(不知道在這一點上,我有django orm命令對象實例,因此可以這樣做)設置相關模型的順序或者重新實現hydrate_m2m甚至save_m2m,關於如何做到這一點的任何提示?

回答

0

感謝您的回答,我真的沒有訂單,但在我的情況下,它必須是這樣的數據代表要創建的訂單和相關數據來填充中間表OrderProduct(json產品字段),所以想法是在同一個請求上給用戶關於訂單和相關數據的API傳遞信息,例如創建一個新的訂單的用戶將具有以下數據

{ 
    "products": { 
     "product": "/products/1", 
     "quantity": 4, 
     "unit_price": 5 
    } 
} 

這些數據應生成以下數據庫POST註冊

Order 
    # with and auto generated id 

OrderProduct 
    order # which points to the auto generated id 
    product # points to a previous registered product 

如果我通過了秩序場我沒有任何有效的ID在這一時刻(類雞蛋問題),因爲訂單尚未保存在數據庫中,tastypie數據流會將訂單保存在ModelResource.obj_save方法中,並且該方法將調用ModelResource.save_m2m,該模型創建OrderProduct註冊,其中異常發生。

所以我需要知道在save_m2m嘗試保存OrderProduct之前,爲了隱式設置該引用,必須實現哪個tastypie掛鉤。