如何加速Django过滤语句

时间:2012-12-06 15:21:45

标签: python django filter

我有一些django代码如下。我只是过滤不同的对象,并尝试获得fitler结果的总数。然后将这些数字传递给html页面。 在html页面中,我只显示这些总数。就是这样。

但是,当用户访问此页面时,速度确实很慢。我看不到代码的任何改进,可以加快程序。 有没有人对代码提出任何加速建议,或者我能做的就是升级服务器?

我在考虑在数据库中创建这些表的视图或索引。但是我没有理解如何在django中这样做。我也可以在数据库中直接进行,但是如何从django访问数据库中的视图?

try:       
    p_r = P.objects.get(p_id=rec_id, f__f_id=f_id, d__n=d)
    s = S.objects.get(r=p_r)
except S.DoesNotExist:
    s = None
except S.MultipleObjectsReturned:
    s = S.objects.filter(r=p_r)


try:
    b = B.objects.filter(r=p_r)
except B.DoesNotExist:
    b = None

bu = {}
if b != None and len(b) > 0:
    bu['count'] = len(b)

try:
    a = A.objects.filter(r=p_r)
except A.DoesNotExist:
    a = None

 an = {}
if a != None and len(a) > 0:
    an['count'] = len(a)


try:
    ar = AR.objects.filter(r=p_r)
except AR.DoesNotExist:
    ar = None

ad = {}
if ar != None and len(ar) > 0:
    ad['count'] = len(ar)




try:
    c = C.objects.filter(r=p_r)
except C.DoesNotExist:
    c = None

co ={}
if c != None and len(c) > 0:
    co['count'] = len(c)



try:
    p_e = []
    ev = E.objects.all()
    for e in ev:
      if e.r_o.p_id == rec_id and e.r_o.record.f.f_id == f_id:
      patient_events.append(e)
except E.DoesNotExist:
    ev = None


ph = {}
if p_e and len(p_e) > 0:
    ph['count'] = len(p_e)
Log().add(request, "View", "I", 'pr', p_r.id)
response_dict.update ({'record': p_r,
                     'summary': s,
                     'bu': bu,
                     'an': an,
                     'ad': ad,
                     'co': co,
                     'ph': ph,
                     'p_id': rec_id,
                     'f_id': f_id,
                     'd': d_id,
                     })
return render_to_response('records/detail.html',response_dict, context_instance=RequestContext(request))

1 个答案:

答案 0 :(得分:2)

以下是我从您的代码中注意到的内容:

  1. 在我的评论中,您在使用try方法时无需使用filter块,因为它会返回空QuerySet并且不会引发{{} {1}}例外。您可以替换这样的块:

    DoesNotExist

    只有:

    try:
        b = B.objects.filter(r=p_r)
    except B.DoesNotExist:
        b = None
    
  2. 如果要计算b = B.objects.filter(r=p_r) 的对象,QuerySet方法就是您想要的。所以你可以在代码中替换这样的块:

    count()

    只有:

    try:
        b = B.objects.filter(r=p_r)
    except B.DoesNotExist:
        b = None
    
    bu = {}
    if b != None and len(b) > 0:
        bu['count'] = len(b)
    
  3. 似乎模型b = B.objects.filter(r=p_r).count() # Will return 0 or more AARBC与您的S模型有关系,所以你最好只使用模板中的相关集合。实际上,也许您应该使用select_related来避免额外的数据库命中

  4. 也许您可以获取P对象并在模板中使用其相关对象来显示计数。在您看来:

    P

    在你的模板中:

    p_r = P.objects.select_related().get(p_id=rec_id, f__f_id=f_id, d__n=d)
    
  5. 在您的代码的这一部分:

    <p>A quantity: {{ record.A_set.all.count }}</p>
    <p>B quantity: {{ record.B_set.all.count }}</p>
    <p>C quantity: {{ record.C_set.all.count }}</p>
    ....
    

    你不需要for循环,你只能使用try: p_e = [] ev = E.objects.all() for e in ev: if e.r_o.p_id == rec_id and e.r_o.record.f.f_id == f_id: patient_events.append(e) except E.DoesNotExist: ev = None 方法(对不起,如果我做错了但是你明白了):

    filter
  6. 考虑到所有这些,这可能看起来像代码的第二个版本:

    p_e = E.objects.filter(r_o__p__id=rec_id, r_o__record__f__f__id=f_id)