0

次のようないくつかの django コードがあります。さまざまなオブジェクトをフィルタリングして、フィルタ結果の総数を取得しようとしています。そして、これらの数値を 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))
4

1 に答える 1

2

あなたのコードから私が気づいたことは次のとおりです。

  1. try私のコメントから、メソッドを使用するときにブロックを使用する必要はありません。filterこれは、空を返し、例外が発生QuerySetしないためDoesNotExistです。次のようにブロックを置き換えることができます。

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

    だけで:

    b = B.objects.filter(r=p_r)
    
  2. のオブジェクトを数えたい場合はQuerySetcount()メソッドが必要です。したがって、コードで次のようにブロックを置き換えることができます。

    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)
    

    だけで:

    b = B.objects.filter(r=p_r).count() # Will return 0 or more
    
  3. models AARBCおよびSはモデルと関係があるように見えるPため、テンプレートで関連セットを使用するだけの方がよいでしょう。select_related実際、余分なデータベースへのヒットを避けるために使用する必要があるかもしれません

  4. おそらく、オブジェクトを取得しP、テンプレート内で関連するオブジェクトを使用してカウントを表示できます。あなたの見解では:

    p_r = P.objects.select_related().get(p_id=rec_id, f__f_id=f_id, d__n=d)
    

    あなたのテンプレートで:

    <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>
    ....
    
  5. コードのこの部分では:

    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
    

    for ループは必要ありません。filterこれには method しか使用できません (私のやり方が間違っていたら申し訳ありませんが、アイデアはわかります)。

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

これらすべてを念頭に置くと、これはコードの 2 番目のバージョンのように見えるかもしれません。

p_r = P.objects.select_related().get(p_id=rec_id, f__f_id=f_id, d__n=d)
ph = E.objects.filter(r_o__p__id=rec_id, r_o__record__f__f__id=f_id).count()

Log().add(request, "View", "I", 'pr', p_r.id)
response_dict.update ({'record': p_r,
                     '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))
于 2012-12-06T16:42:56.180 に答える