2016-09-13 27 views
0

我們其中有一個領域last_updated這是我們與MySQL-工作臺設置具有以下屬性的資源表:MySQL在更新不觸發Django的/ TastyPie REST API

數據類型:TIMESTAMP

NN( NOTNULL)是checked

默認:CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

當我修改行通過工作臺和應用它,在last_updated領域適當更新。

當我使用REST API,我們已經設置,併發出認沽:

update = requests.put('http://127.0.0.1:8000/api/resources/16', 
      data=json.dumps(dict(status="/api/status/4", timeout=timeout_time)), 
      headers=HEADER) 

我可以適當地改變的任何值(包括狀態和超時,並收到204響應),但last_updated不更新。

Django's model documentation說在這種情況下,它應該發送一個UPDATE

任何人都有想法,爲什麼它缺少這些更新?

我可以提供關於我們特定Django/tastypie設置的更多詳細信息,但只要他們發出UPDATE,他們應該觸發數據庫ON UPDATE

回答

0

與spencer7593的answer的額外信息,我能夠追查如何通過tastypie做到這一點:

BaseModelResource.save()(從tastypie/resources.py):

def save(self, bundle, skip_errors=False): 
    if bundle.via_uri: 
     return bundle 

    self.is_valid(bundle) 

    if bundle.errors and not skip_errors: 
     raise ImmediateHttpResponse(response=self.error_response(bundle.request, bundle.errors)) 

    # Check if they're authorized. 
    if bundle.obj.pk: 
     self.authorized_update_detail(self.get_object_list(bundle.request), bundle) 
    else: 
     self.authorized_create_detail(self.get_object_list(bundle.request), bundle) 

    # Save FKs just in case. 
    self.save_related(bundle) 

    # Save the main object. 
    obj_id = self.create_identifier(bundle.obj) 

    if obj_id not in bundle.objects_saved or bundle.obj._state.adding: 
     bundle.obj.save() 
     bundle.objects_saved.add(obj_id) 

    # Now pick up the M2M bits. 
    m2m_bundle = self.hydrate_m2m(bundle) 
    self.save_m2m(m2m_bundle) 
    return bundle 

需要在你的類中重寫,以便您可以更改Django save(),它具有我們要修改的update_fields參數:

if obj_id not in bundle.objects_saved or bundle.obj._state.adding: 
     bundle.obj.save() 

,例如:

class ResourcesResource(ModelResource): 
    # ... 
    def save(self, bundle, skip_errors=False): 
     # ... 
     if obj_id not in bundle.objects_saved or bundle.obj._state.adding: 
      resource_fields = [field.name for field in Resources._meta.get_fields() 
           if not field.name in ['id', 'last_updated']] 
      bundle.obj.save(update_fields=resource_fields) 
     # ... 

這正確地排除從SQL UPDATElast_updated柱。

1

我懷疑由Django發佈的UPDATE語句可能包括對last_updated列的賦值。這只是一個猜測,沒有提供足夠的信息。

但如果Django的模型包含last_updated列,該列是從數據庫到模型中取出,相信保存()將一個值分配給last_updated列,UPDATE語句。

https://docs.djangoproject.com/en/1.9/ref/models/instances/#specifying-which-fields-to-save


考慮的行爲,當我們發出一個UPDATE語句是這樣的:

UPDATE mytable 
    SET last_updated = last_updated 
     , some_col = 'some_value' 
    WHERE id = 42 

因爲UPDATE語句在last_updated列分配一個值時,自動分配給時間戳列不會發生。語句中分配的值優先。

要自動分配到last_updated,該列必須從SET子句中省略,例如,

UPDATE mytable 
    SET some_col = 'some_value' 
    WHERE id = 42 

要進行調試,您需要檢查實際的SQL語句。

+0

是的,我一直在試圖解決這個問題。到目前爲止沒有骰子。我同意似乎可能,雖然在那種情況下我需要阻止它自動填充該字段。 – TemporalWolf

+0

我發佈了我找到的解決方案......您確實正確地確定了問題並指出了我朝着正確的方向發展。 – TemporalWolf