【问题标题】:Faster way to get class instance from Ajax从 Ajax 获取类实例的更快方法
【发布时间】:2018-01-10 23:47:30
【问题描述】:

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

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() 上使用else 条件吗?为什么不应该是ajax?

谢谢

【问题讨论】:

    标签: json ajax serialization django-queryset jsonresponse


    【解决方案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 使用,我会在 else 或基本函数级别的末尾添加 return HttpResponseBadRequest()

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-21
      相关资源
      最近更新 更多