django模板中的两个外键和一个值
Posted
技术标签:
【中文标题】django模板中的两个外键和一个值【英文标题】:Two foreign keys and a value in django template 【发布时间】:2011-04-14 15:03:21 【问题描述】:我是 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 中正确执行此操作?
非常感谢,
【问题讨论】:
【参考方案1】:作为@DZPM suggested,您应该考虑将逻辑保留在您的视图中。 [愚蠢] 我曾经发明了自己的“表”数据结构来做一些非常相似的事情。该表的行对应于X
,列对应于Y
,单元格对应于Z[X, Y]
。然后我写了get_row
和get_cell
过滤器来完成模板中的技巧。 [/sheepish]
也就是说,您可以使用一对自定义过滤器来实现您想要的。这个解决方案比较冗长。
@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 %
【讨论】:
宾果游戏!非常感谢 - 那是缺少的链接(自定义过滤器)。【参考方案2】:您应该将逻辑保留在您的视图中。为什么不直接过滤 z_list 呢?
z_list = Z.objects.filter(x__name__contains=x_pattern, y__name__contains=y_pattern)
【讨论】:
我可以过滤视图中的列表,但它仍然不能帮助我正确显示它(即我需要将 (x,y) 密钥对映射到 z[x,y] 中的值模板,以便在适当的表格单元格中显示它)。我在这里错过了什么吗?【参考方案3】:另一种方法是在您的视图中创建一个生成器,然后将其发送到您的模板上下文:
# 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 %
【讨论】:
【参考方案4】:我将自定义过滤器和函数的概念作为第一类对象组合在一起,将模板过滤器制成函子(函数对象)。
这是我最终做的:
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>
感谢大家的帮助!
【讨论】:
以上是关于django模板中的两个外键和一个值的主要内容,如果未能解决你的问题,请参考以下文章