2017-08-03 58 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()