2010-09-20 30 views
5

我是django的新手,所以這個問題可能是愚蠢的,但請隨時教我正確的方式,如果你知道它。 我試着用Google搜索這個問題,但我仍然處於虧損狀態。 這裏是我的問題:Django模板中的兩個外鍵和值

我在我的模型類有兩個外鍵:

class X(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Y(models.Model): 
    name = models.CharField(max_length=30) 
    def __unicode__(self): 
     return name 

class Z(models.Model): 
    name = models.CharField(max_length=30) 
    x = models.ForeignKey(X) 
    y = models.ForeignKey(Y) 
    def __unicode__(self): 
     return name 

在我看來,我得到X對象的部分列表和Y的對象,像這樣的部分列表:

def MyView(x_pattern, y_pattern): 
    x_list = X.objects.filter(name__contains=x_pattern) 
    y_list = Y.objects.filter(name__contains=y_pattern) 
    z_list = Z.objects.all() 
    return render_to_response({'x_list': x_list, 'y_list': y_list, 'z_list': z_list}) 

在我的模板,我想能夠顯示一個表像這樣:

<table> 
    <tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
    </tr> 
    {% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td> 
     <!-- here I need help: 
      I need to display z[x, y] if it exists, or "N/A" otherwise. 
     --> 
    </td> 
    {% endfor %} 
    </tr> 
    {% endfor %} 

如何在django中正確執行此操作?

非常感謝,

回答

0

您應該保持在您的視圖的邏輯。你爲什麼不過濾那裏的z_list?

z_list = Z.objects.filter(x__name__contains=x_pattern, y__name__contains=y_pattern) 
+0

我可以在視圖中過濾列表,但它仍然無法幫助我正確顯示它(即,我需要將(x,y)密鑰對映射到模板中的z [x,y]值以顯示它在一個適當的表格單元格中)。我在這裏錯過了什麼嗎? – mfynf 2010-09-20 12:10:46

1

作爲@DZPM suggested,您應該考慮將邏輯保留在您的視圖中。 [羞怯]我曾經發明瞭我自己的「Table」數據結構來做一些非常相似的事情。該表具有對應於X的行,對應於Y的列和對應於Z[X, Y]的單元。然後,我寫了get_rowget_cell過濾器來完成模板中的技巧。 [/ shaish]

這就是說,你想要什麼可以使用一對自定義過濾器來完成。這個解決方案比較冗長。

@register.filter 
def x_is(value, x): 
    return value.x == x 

@register.filter 
def y_is(value, y): 
    return value.y == y 

您可以使用該模板這些過濾器,如下圖所示:

{% if z|x_is:x and z|y_is:y %} 
    {{ z }} 
{% else %} 
    N/A 
{% endif %} 
+0

賓果!非常感謝 - 這是缺少的鏈接(自定義過濾器)。 – mfynf 2010-09-20 12:54:22

0

另一種方法是建立在你看來發電機,然後將其發送到您的模板背景:

# nested inside your view function 
def x_and_z_list(y): 
    for x in x_list: 
     z_obj = x.z_set.filter(y=y) 
     z_name = z_obj or 'N/A' 
     yield {'x': x, 'z': z_name} 
return render_to_response('mytemplate', {'list_generator': x_and_z_list} 

那麼您的範本看起來像這樣:

{% for y in y_list %} 
    <tr> 
     <td>{{ y }}</td> 
     {% for pair in list_generator.y %} {# pair is the dict you yielded before #} 
      <td>{{ pair.x.name }}: {{ pair.z }}</td> 
     {% endfor %} 
    </tr> 
{% endfor %} 
0

我將自定義過濾器和函數的概念合併爲一個將模板過濾器變爲函子(函數對象)的第一類對象。

這裏是我落得這樣做:

def z_filter(x, y): 
    z_list = list(Z.objects.filter(x, y)) 
    return z_list.pop().name or 'N/A' 
register.filter(z_filter) 

模板:

{% load z_filter %} 
<table> 
<tr> 
    <td>Y</td> 
    {% for x in x_list %} 
    <td>{{ x }}</td> 
    {% endfor %} 
</tr> 
{% for y in y_list %} 
    <tr> 
    <td>{{ y }}</td> 
    {% for x in x_list %} 
    <td>{{ x|z_filter:y }}</td> 
    {% endfor %} 
    </tr> 
{% endfor %} 
</table> 

謝謝大家的幫助!