从Ajax获取类实例的更快方法

时间:2017-08-03 11:36:44

标签: json ajax serialization django-queryset jsonresponse

我有这个简单的函数来从数据库中检索数据:

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_object is 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_objectmy_object为ForeignKey的类的实例。我想要的是?如果存在my_object,我想查看是否存在一个相应的my_other_object并找到其中一个字段的值。对于每个my_object,只有一个my_other_object或没有if request.is_ajax()。我的解决方案有效,但也许有更快的方法。

另外:我应该在#define ARGS(list) () 上使用其他条件吗?为什么不应该是ajax?

谢谢

1 个答案:

答案 0 :(得分: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]表示法的第一个项目一样,在first()上调用filter()与调用get()具有完全相同的性能,不同之处在于Python上发生的情况侧。

2)你的解决方案非常好。对于这个用例,没关系。

奖金问题:如果视图仅用于通过ajax使用,我会在return HttpResponseBadRequest()或仅在基本功能级别添加else