2017-08-03 77 views
0

得到的類實例我有這個簡單的函數從數據庫retrive數據:更快的方式從阿賈克斯

function find_object() { 
    $.ajax({type: 'POST', 
     url: '/find-object/', 
     data: { 
      position: position, 
     }, 
     success: function (result_list) { 
      if (result_list.result === 'OK') { 
       console.log(result_list.data.myobject) 
      } else { 
       console.log('not found') 
      }; 

     } 
    }); 
}; 

這裏的view

def find_object(request): 
    if request.is_ajax(): 
     position = request.POST.get('position', None); 
     try: 
      my_object=My_Class.objects.get(coordinate=position) 
     except: 
      return JsonResponse({'result': 'None'}) 
     my_other_object=My_Other_Class.objects.filter(my_ForeignKey_field=my_object) 
     if my_related_object: 
      my_field=my_other_object.my_field 
      #do things 
     return JsonResponse({'result': 'OK', 'data': { 'myobject': my_object }}) 

它給出錯誤,因爲my_objectis not JSON serializable,但它不是查詢集,因爲它來自.get()所以我不能像這樣序列化:

my_object_json=serializers.serialize('json', my_object) 

在第一個請求中,我使用的是.get(),因爲它比.filter()(當例外情況很罕見,並且是)更快。對於每個position,只有一個my_object或(很少)沒有。在第二個請求中,我使用.filter(),因爲例外情況並不罕見。

所以問題:

1)是更快地使用.filter()代替.get()然後上面連載my_object喜歡或者有一些其他的方式?也許是一個沒有JsonResponse?我需要所有字段的對象

2)my_other_object是一個類的實例,其中my_object是ForeignKey。我想要的是?如果my_object存在,我想看看是否存在相應的my_other_object並找到他的一個字段的值。對於每個my_object,只有一個my_other_object或沒有。我的解決方案可行,但也許有更快的方法來做到這一點。

另外:我應該在if request.is_ajax()上使用其他條件嗎?爲什麼不應該是ajax?

謝謝

回答

1

0)的Django模型實例不是序列化。您無法序列化查詢集,但這並不意味着您可以序列化一個實例。一個簡單的方法,使之序列化是讓自己的價值觀這樣

my_object_serialized = list(my_object.values('the', 'fields', 'that', 'you', 'need')) 

1)這需要的時間長一點的答案。 get()filter()之間存在性能差異,因爲get()可以返回它在數據庫中看到的第一個實例,但filter()必須遍歷整個表。但是,第二個您將filter()更改爲filter()[0]的值應該等於get()的性能。這幾乎是無關緊要的。爲什麼?

filter()get()分開存在,因爲它們意味着彼此之間的用法不同。如果您知道數據庫中只有一個這樣的對象,或者您想驗證您只有一個對象,那麼您使用get(),因爲當有0個或更多查詢事件的實例時它會引發異常。出於同樣的原因,您甚至可以執行MyModel.objects.filter(myfield=myvalue).get() - get()驗證只有一個對象。
如果你只想得到第一個對象,並且你不關心有多少個,那麼首選的方法是使用filter().first()模式,如果沒有則返回第一個對象或返回None。就像獲得[0]表示法的第一項一樣,在filter()上調用first()與調用get()具有完全相同的性能,不同之處在於Python方面發生的情況。

2)您的解決方案非常好。對於這個用例,沒關係。獎勵問題:如果視圖僅用於通過ajax使用,那麼我會在末尾添加return HttpResponseBadRequest(),最後可以是else,也可以僅在基本功能級別上添加return HttpResponseBadRequest()