【问题标题】:Django template multiple tables with only slightly modified dataDjango模板多个表,数据仅稍作修改
【发布时间】:2018-05-18 09:30:30
【问题描述】:

我想在我的页面上显示两个表格,其中只有一个列被修改,其他所有列都相同。我想知道是否有任何其他方法比简单地循环两次并创建表两次更有效?

我现在要做的是:

# Example models
class Question(models.Model):
    question = models.TextField()

class Answer(models.Model):
    question = models.ForeignKey(Question)
    score = models.Integerfield()

    SCORETYPES = (
    (1, 'initial'),
    (2, 'current'),
    )

    scoreType = models.Integerfield(choices=SCORETYPES)

    def __str__(self):
        return "Answer: " + scoreType

在我看来,我会将问题与答案联系起来:

# Example view
questions = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers')).all()

这意味着我的问题对象对于每个问题看起来都是这样的

question.answers = [<Answer: Initial>, <Answer: Current>]

然后在我的模板中我会像这样打印它们

# Example template
{% for question in questions %}
    {% for answer in question.answers %}
        <p>{{ answer.scoreType }}: {{ answer.score }}</p>
    {% endfor %}
{% endfor %}

这可行,但现在我想为所有初始分数创建一个表,为所有当前分数创建一个表,这样你就会得到这样的结果:

Initial Scores

Question    Score
Q1          2
Q2          3

Current Scores

Question    Score
Q1          1
Q2          4

如您所见,这需要我使用 for 循环两次,并且每次检查 scoretype 是 1 还是 2。是否有更有效的方法来做到这一点,或者这是要走的路?我有很多问题,我想尽可能高效地工作。

提前致谢!

【问题讨论】:

    标签: python django python-3.x django-templates


    【解决方案1】:

    一个可能的解决方案是使用两个不同的查询集,Answer.scoreType 上的过滤器,即:

    # views
    
    def myview(request, ...):
        qs = Question.objects.prefetch_related(Prefetch('answer_set', to_attr='answers'))
        initial = qs.filter(answer__scoreType=1)
        current = qs.filter(answer_scoreType=2)
        context = {"initial": initial, "current": current)
        # etc
    

    然后

    # template:
    
    <h1>Initial scores</h1>
    {% for q in initial %}
       {% for answer in q.answers %}
        # ...
       {% endfor %}
    {% endfor %}
    
    <h1>Current scores</h1>
    {% for q in current %}
       {% for answer in q.answers %}
        # ...
       {% endfor %}
    {% endfor %}
    

    但这意味着您将有两个数据库查询,这也可能不是最佳的(取决于您的数据集大小等)。

    另一种解决方案是在视图中手动过滤掉您的查询集,但如果您想保持查询集按问题排序,这将开始变得棘手,会消耗更多内存,并且最终可能会比发出两个不同的查询(同样,取决于您的数据集大小等)。

    长话短说,“正确”的解决方案实际上取决于您的实际数据集 - 特别是您通常在视图中有多少问题/答案。如果这些数据集非常小,则在视图中甚至直接在模板中进行过滤可能足够快,但是纯 python 代码或(更糟糕的)模板代码与 SQL db 内置过滤的相对性能将很快成为第一个选项( 2 个不同的查询)更快。

    【讨论】:

    • 不会因为您在查询集上使用过滤器而对数据库进行两次额外查询吗?
    • @AlexanderSchillemans 是的,这就是我要提到的内容;)
    • @AlexanderSchillemans cf 我编辑的答案。只是为了完整起见,请记住 django 查询集是惰性的——你只有在实际开始迭代数据库时才访问数据库——所以你只会有 一个 额外的查询(=> 你会有总共两个查询,而不是一个)。
    • 啊,我明白了。这确实比我现在使用的要多一个查询。感谢您的编辑,我猜多做一个查询比在模板中进行过滤要快。我会试试看。谢谢!
    猜你喜欢
    • 2020-06-02
    • 1970-01-01
    • 2016-01-03
    • 2020-05-30
    • 2011-04-01
    • 2019-02-26
    • 2013-01-06
    • 2015-07-01
    • 1970-01-01
    相关资源
    最近更新 更多