【问题标题】:How to query another Django model in template view based on the relation to another model如何根据与另一个模型的关系在模板视图中查询另一个 Django 模型
【发布时间】:2020-12-12 17:44:37
【问题描述】:

我有这些模型

class Protocol(models.Model):
    name = models.CharField(max_length=200)

class Description(models.Model):
    name = models.CharField(max_length=200)
    protocol = models.ForeignKey(Protocol)

class Trait(models.Model):
    desc = models.CharField(max_length=200)
    protocol = models.ForeignKey(Protocol)

class State(models.Model):
    desc = models.CharField(max_length=200)
    trait = models.ForeignKey(Trait)

class Expression(models.Model):
    state = models.ForeignKey(State)
    description = models.ForeignKey(Description)

所以一个协议(例如协议“A”)由一定数量的特征(例如身高、体重、颜色)组成。每个特征可以有多个状态(例如低、中、高)。那么,描述是与特定协议相关的表达式的集合。例如,描述 #1 由协议“A”组成,由两个表达式组成:身高 -> 低,体重 -> 高;但未指定特征颜色。

基本上,我想做的是在模板视图中显示 all 链接到所选描述的特定协议的 Traits,然后是相应的 表达式 对于某些 Trait 也可以为空。

像这样:

| Trait  | Expression |
|--------+------------|
| height |            |
| weight | high       |
| color  | blue       |

使用 shell 我可以很容易地返回我需要的东西

# Select a Description
desc = Description.objects.first()

# Get the protocol
protocol = desc.protocol

# Get all traits in the selected protocol
all_traits = protocol.trait_set.all()

# Get all the expressions in this description
expressions = desc.expression_set.all()

# Print all traits within the selected protocol and their related expression (if any)
for trait in all_traits:
    print(trait.desc)
    expr = expressions.filter(state__trait_id = trait.id).first()
    print(expr.state.desc)

但是,我不知道如何在视图中执行此操作,尤其是我想继续使用 DetailView,但如果不可能,这不是严格要求。 有什么办法吗?

谢谢

【问题讨论】:

    标签: python django django-models django-templates


    【解决方案1】:

    我找到了一种方法来做到这一点,尽管我并不完全满意,因为我觉得这不是一个非常优雅的解决方案。

    我在我的应用程序内的templatetags/ 目录中创建了一个description_extras.py(不要忘记将__init__.py 视为一个包)

    description_extras.py 中,我创建了一个自定义过滤器,如下所示:

    from django import template
    
    register = template.Library()
    
    @register.filter
    def expr_trait(expression,trait_id):
        return expression.filter(state__trait_id = trait_id).first()
    

    然后在模板中,我加载自定义过滤器

    {% load description_extras %}
    

    然后我可以这样调用过滤器:

    {% for trait in description.protocol.trait_set.all %}
        <tr>
            <td>{{ trait.desc }}</td>
            <td>{{ description.expression_set.all|expr_trait:trait.id }}</td>
        </tr>
    {% endfor %}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2020-12-09
      • 2015-10-14
      • 2015-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多