2014-01-16 54 views
0

比方說,我有兩個Django模型ModelA和ModelB。 ModelA的一個對象的創建應該在某些情況下觸發ModelB的一個對象的創建。目前,不使用Tastypie,我有一個控制對象的創建以下觀點:使用Tastypie和Django創建多個POST請求的對象的正確方法

def new_A_created_view(request): 
    post_data = json.loads(request.body) 
    ... parse post arguments ... 

    a = ModelA.objects.create(...) 
    if conditions_are_met(...): 
     b = ModelB.objects.create(...) 

現在我想過渡到一個REST API,並使用TastyPie我有以下資源:

class ModelAResource(ModelResource): 

    class Meta: 
     queryset = ModelA.objects.all() 
     authorization = Authorization() 
     ... 

    def hydrate(self, bundle): 
     if bundle.request.META['REQUEST_METHOD'] == 'POST': 
      ...compute objects attributes from received post data ... 

我知道以下選項來創建相應的B對象:

  1. 覆蓋保存或post_save方法。覆蓋Save方法或MODELA添加post_save信號,對象B的創作緊跟節約A.問題的行爲我在這種方法中看到:

    • 創建對象的ModelB可能不取決於邏輯屬性出現在A中,而是包含在POST請求中的參數中。
    • 我失去了views.py中很好的'控制器'邏輯,轉而使用模型中更隱蔽的邏輯。
  2. 覆蓋Resource.obj_create在ModelAResource因此它創建一個對象MODELA以及基於所述資源POST信息的ModelB對象(如果需要)。在這種情況下,我覺得物體的創作在某種程度上被遮蔽了。

我失蹤的任何解決方案?什麼是最好的方法來做到這一點?

+0

你能告訴我們ModelA和ModelB是如何在'models.py'中聲明的嗎?他們都有彼此的關係嗎? – adityasdarma1

+0

在我的具體情況下,ModelA將ModelB作爲其領域之一。所以在ModelA裏面會有一個定義爲object_b = models.ForeignKey(ModelB)的字段。儘管ModelB與ModelA沒有直接關係。 –

回答

0

最後,我在資源類中預先加了一個url,覆蓋了資源的入口點,並將其引導至執行所需邏輯的類的自定義函數。我也從資源中刪除了任何補充水分。

class ModelAResource(ModelResource): 

    class Meta: 
     queryset = ModelAResource.objects.all() 
     authentication = MyOwnAuthentication() 
     resource_name = 'modelAResource' 
     allowed_methods = ['post'] 

    def prepend_urls(self): 
     return [url(r"^(?P<resource_name>%s)%s$" % 
       (self._meta.resource_name, trailing_slash()), 
       self.wrap_view('process_resource'), name="process_resource")] 

    def process_resource(self, request, **kwargs): 
     self.method_check(request, allowed=['post']) 
     self.is_authenticated(request) 

     data = self.deserialize(request, request.body) 

     param1 = data.get('param1name', '') 
     param2 = data.get('param2name', '') 

     ModelA.objects.create(...) 
     if it_should_be_done(param1, param2): 
      ModelB.objects.create(...) 

當然,這有它的警告,因爲我已經覆蓋默認的URL訪問API,但對我來說,這不是問題,因爲API只公開對資源的一個操作(創建)。無論如何,前綴的網址可以是任何東西。

0

因爲ModalA有關係ModelB,和你想要的ModelB自動保存時MODELA保存,你的資源的聲明應該是,

from tastypie.resources import ModelResource 
from tastypie import fields 
from yourapp.models import ModelA, ModelB 

class ModelAResource(ModelResource): 
    model_b = fields.ForeignKey(
     'yourapp.resources.ModelBResource', 
     'model_b', 
     full=True 
    ) 
    # .... 
    class Meta: 
     queryset = ModelA.objects.all() 
     # .... 

class ModelBResource(ModelResource): 
    # .... 
    class Meta: 
     queryset = ModelB.objects.all() 
     # .... 

當你POST/PUT/PATCH,你只要把model_b在您的數據就像你創建/編輯model_b

例如

{ 
    "field1_of_model_a" : "content_of_field1_of_model_a", 
    "field2_of_model_a" : "content_of_field2_of_model_a", 
    "model_b" : { 
     "field_1_of_model_b" : "content_of_field_1_of_model_b", 
     "field_2_of_model_b" : "content_of_field_2_of_model_b" 
    } 
} 
+0

Thanks @ adityasdarma1,我沒有考慮過這些選項,儘管它不完全是我想要做的。 ModelB應該在服務器中自動創建,而不是通過POST接收。爲了澄清我之後的內容,ModelA只是一個url,ModelB是該url的域名和一些統計信息。所以當ResourceA的一個POST被創建時,我會檢查該網址的域對象是否存在於數據庫中,如果沒有,就創建它。我想提出更一般的問題,但這是我的特殊情況:)。 –

相關問題