【问题标题】:Querying Querysets in Django? Attempting to return a step and then the sub-steps underneath it在 Django 中查询查询集?尝试返回一个步骤,然后返回它下面的子步骤
【发布时间】:2019-09-01 00:53:35
【问题描述】:

我认为这实际上非常直观,但我无法弄清楚。

所以我有一个名为 SWS_Document 的模型。然后我有 SWS_Document_Step,它具有 SWS_Document 的外键。之后我有第三个模型 SWES_Step,它有一个外键到 SWS_Document_Step。本质上,SWES_Document_Step 是 SWS_Document_Step 的子步骤。

示例。它将是“将黄油混合到配方中”将是 SWS_Document_Step。而 SWES_Document_Step__id=1 将是“将黄油放入微波炉安全碗中”。 SWES_Document_Step__id=2 将是“用微波炉加热黄油 30 秒。”

这些是“将黄油混合到配方中”的子步骤。

class SWS_Document(models.Model):

    machines = models.ManyToManyField(Machine, related_name='SWS_documents')
    document_description = models.CharField(max_length=150, default="")
    pub_date = models.DateTimeField(auto_now=True)

class SWS_Document_Step(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    document_number = models.ForeignKey(SWS_Document, on_delete=models.CASCADE)
    sws_sequence_number = models.PositiveIntegerField(editable=True, null=True)

class SWES_Step(models.Model):

    STEP_TYPE_CHOICES = (
        ('People', 'People'),
        ('Quality', 'Quality'),
        ('Velocity', 'Velocity'),
        ('Cost', 'Cost'),
    )
    sws_document_id = models.ForeignKey(SWS_Document_Step, on_delete=models.CASCADE, null=True)
    swes_description = models.CharField(max_length=500)
    swes_step_type = models.CharField(max_length=8, choices=STEP_TYPE_CHOICES, blank=True)
    pub_date = models.DateTimeField(auto_now=True)

所以在我的 view.py 中我已经采取了 swsallsteps。

def DocumentView(request, document_id):
    # final goal should be to pass a list full of lists...
    # e.g. [
    #[name1, [hazard1, hazard2], [assessment1, assessment2]],
    #[name2, [hazard3, hazard4], [assessment3, assessment4]],
    #]
    steps = []
    swsallsteps = SWS_Document_Step.objects.filter(document_number=document_id)
    swesallsteps = SWES_Step.objects.filter(sws_document_id=document_id)
    return render(request, 'StandardWorkDocuments/document.html', {
        'swsallsteps': swsallsteps,
        'swesallsteps': swesallsteps,
    })

然后在 Document.html 中我有几个 for 循环。

{% for step in swsallsteps %}
    <button class='collapsible'>{{ step.sws_sequence_number }} - {{ step.sws_work_element_description}} - <em><b>{{step.sws_step_type}}</b></em> - published - {{step.pub_date}}</button>
    <div class="content">
        {% for swessteps in swesallsteps %}
            <p>{{swessteps.swes_description}}</p>
        {% endfor %}
    </div>
{% endfor %}

基本上,我相信我想要得到的是查询中的查询集。所以它会是[[将黄油混合到配方中,[将黄油放入微波炉安全碗中,将黄油微波炉加热 30 秒]]

This is what I'm currently getting

This is what I'd hope to get, with a few dumby points put in to show for example

【问题讨论】:

    标签: python django django-views django-queryset


    【解决方案1】:

    您可以(并且应该)通过父项访问嵌套项。 Django 文档中有一些关于访问相关对象的有用examples,在这个question 中,您可以找到有关访问相关对象的更详细的纲要;例如,related_name 属性可以替换 model_set 语法并提高可读性(如果选择得当)。

    你的第二个循环应该是这样的:

    {% for swes_step in step.swes_step_set.all %}
        <p>{{swes_step.swes_description}}</p>
    {% endfor %}
    

    您现在不是从单独的查询集而是从父步骤访问第二步级别。您可以废弃第二个查询集 (swesallsteps)。

    为避免发出大量数据库查询,您应该使用prefetch_related 以尽可能少的步骤获取所有数据:

    swsallsteps = (SWS_Document_Step.objects
        .filter(document_number=document_id)
        .prefetch_related('swes_step_set')
    )
    

    【讨论】:

    • 你从哪里得到 swes_step_set? '_set' 部分是否添加到“swes_step”的模型中,本质上是“Model”+“_set”?还是我错过了什么?
    • 很好,这是您访问在另一个模型上定义的 x 对多关系的方式。请参阅更新答案中的链接。
    • 那么,“_set”是面向对象编程的一部分,您可以对查询做什么?如果我想获取 SWES_Step 的相关信息怎么办?因为我那里也有相关资料。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-04
    • 1970-01-01
    相关资源
    最近更新 更多