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_rowget_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模板中的两个外键和一个值的主要内容,如果未能解决你的问题,请参考以下文章

如何从 Django 模板中的外键访问值

我无法让这个外键表值显示在 django 模板中

django模板获取键和值分开显示

html模板中的django外键表字段

模板中的 Django 外键

在 Django 模板中使用外键作为变量