2010-09-20 70 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> 

谢谢大家的帮助!