2016-07-11 99 views
1

我想減少my_filter_function()中的模板過濾器調用次數。因爲它在模板內部的兩個for-loop中使用。請參閱下面的代碼設置。Django模型查詢調優

class ModelA(models.model): 
    models.ForeignKey(OtherModel1) 

class ModelB(models.model): 
    models.ForeignKey(OtherModel2) 

class ModelC(models.Model): 
    a = models.ForeignKey(ModelA) 
    b = models.ForeignKey(ModelB) 

def my_views(request): 
     return render(request, 'my_template.html', { 
     'a_list': ModelA.objects.all(), 
     'b_list': ModelB.objects.all(), 
    }) 

,並在我的模板,我有

{% for a in a_list %} 
    {% for b in b_list %} 
      {% with b|my_filter_function:a as my_val %} 
         Val: {{my_val}} 
      {% endwith %} 
    {% endfor %} 
{% endfor %} 

上面的模板會會調用my_filter_function過濾功能,我需要找到另一種方式來減少my_filter_function函數調用的數量,因爲過濾器函數現在正在每個模板訪問數千個數據塊。

@register.filter 
def my_filter_function:(b, a): 
     z = ModelC.objects.filter(a=a, b=b) 
     if z.count() > 0: 
      return "OK" 
     else: 
      return "Not OK" 
+0

這段代碼的總體目的是什麼? –

回答

2

這是一個更快的選擇。

取的AB所有的ID在C一次:

z = ModelC.objects.values_list('a_id', 'b_id') 

a_related, b_related = zip(*z) # split into a and b ids 

通過這些對上下文:

def my_views(request): 
     return render(request, 'my_template.html', { 
     'a_list': ModelA.objects.all(), 
     'b_list': ModelB.objects.all(), 
     'a_related': a_related, 
     'b_related': b_related, 
    }) 

,然後在模板中使用if...in。自定義模板過濾器現在可以被丟棄:

{% for a in a_list %} 
    {% for b in b_list %} 
      {% if a.id in a_related and b.id in b_related %} 
       "OK" 
      {% else %} 
       "Not ok" 
      {% endif %} 
    {% endfor %} 
{% endfor %} 

用一個替換過濾器中的所有多個查詢。