Django - 通过外键从子对象中获取值,同时在模板中循环父对象

Django - Fetch values from children via Foreign Key, while looping the parent objects in template

我是 Django 的新手,这可能是一个完全没有经验的问题,但我被困在这种情况下,非常感谢您的帮助。我有以下型号:

class BillType(models.Model):
    name = models.CharField(max_length=200)
    created_on = models.DateTimeField(default=datetime.now, blank=True)

    def __str__(self):
        return self.name
class Bill(models.Model):
    bill_type = models.ForeignKey(BillType, on_delete=models.CASCADE)
    month = models.CharField(max_length=200)
    amount = models.IntegerField()
    due_date = models.CharField(max_length=200)
    note = models.TextField(blank=True)
    recurring = models.BooleanField(default=True)
    currency = models.CharField(max_length=100)
    created_on = models.DateTimeField(default=datetime.now, blank=True)

    def __str__(self):
        return self.month

和以下视图:

def billingOverview(request):
    bill_types = BillType.objects.all()

    context = {
        'bill_types': bill_types,
    }

    return render(request, 'management/billing-overview.html', context)

在模板中,我使用 For 循环遍历 BillType 对象,这部分工作正常。但是,对于在模板中单独呈现的每个循环 BillType 对象,我需要访问并显示与该特定 BillType 对象对应的 'month' 的数据。你能帮我举例说明我该怎么做吗?

谢谢, 博扬

如果需要模板:

                    {% for bill_type in bill_types %}
                    <!-- Billing overview column -->
                    <div>
                        <!-- Billing overview widget -->
                        <div class="bo-widget">
                            <div class="bo-widget-header">
                                <div>
                                    <h2>{{ bill_type.name }}</h2>
                                    <span>Overview of {{ bill_type.name|lower }} bills</span>
                                </div>
                                <a class="bo-addnew-bill" href="{% url 'newBill' bill_type.id %}">+</a>
                            </div>
                            <div class="bo-widget-content">
                                <span>OVERDUE</span>
                                <div class="bo-widget-bill-cont overdue">
                                    <span class="bo-overdue-warning"><i class="fas fa-exclamation-triangle"></i></span>
                                    <div class="bo-bill-info">
                                        <span>January 2020</span>
                                        <div>
                                            <span>2,200 MKD</span>
                                            <p>Due Date: 15 February 2020</p>
                                        </div>
                                    </div>
                                    <div class="bo-bill-actions">
                                        <a class="bo-bill-paid-action" href="javascript:;"><i class="fas fa-check"></i></a>
                                    </div>
                                </div>
                                <span>LATEST BILL</span>
                                <!-- Latest Bill -->
                                <div class="bo-widget-bill-cont">
                                    <div class="bo-bill-info">
                                        <span>{{ MONTH SHOULD GO HERE }}</span>
                                        <div>
                                            <span>2,200 MKD</span>
                                            <p>Due Date: 15 February 2020</p>
                                        </div>
                                    </div>
                                    <div class="bo-bill-actions">
                                        <a class="bo-bill-paid-action" href="javascript:;"><i class="fas fa-check"></i></a>
                                    </div>
                                </div>
                            </div>
                            <div class="bo-see-all">
                                <a href="javascript:;">See all bills</a>
                            </div>
                        </div>
                    </div>
                    {% endfor %}

是的。我知道只需要两行代码就可以解决这个问题,但没关系。我找到了解决方案,以防万一有人需要这个:

在 Bill 模型中,我已将 related_name 'billtype' 添加到 ForeignKey 字段,因此整行现在将是:

bill_type = models.ForeignKey(BillType, on_delete=models.CASCADE, related_name='billtype')

现在,对于视图中的查询,我添加了以下行

bill_types = BillType.objects.all()

为了获取 BillType 模型中的所有账单类型对象;接下来,我添加了以下行

bills = Bill.objects.select_related('bill_type').all()

为了获取 Bill 模型中相关字段的所有对象 'bill_type'。

在模板中,

{% for bt in bill_types %}
<!-- Billing overview column -->
<div>
    <!-- Billing overview widget -->
    <div class="bo-widget">
        <div class="bo-widget-header">
            <div>
                <h2>{{ bt.name }}</h2>
                <span>Overview of {{ bt.name|lower }} bills</span>
            </div>
            <a class="bo-addnew-bill" href="{% url 'newBill' bt.id %}">+</a>
        </div>
        <div class="bo-widget-content">
            <span>OVERDUE</span>
            <div class="bo-widget-bill-cont overdue">
                <span class="bo-overdue-warning"><i class="fas fa-exclamation-triangle"></i></span>
                <div class="bo-bill-info">
                    <span>January 2020</span>
                    <div>
                        <span>2,200 MKD</span>
                        <p>Due Date: 15 February 2020</p>
                    </div>
                </div>
                <div class="bo-bill-actions">
                    <a class="bo-bill-paid-action" href="javascript:;"><i class="fas fa-check"></i></a>
                </div>
            </div>
            <span>LATEST BILL</span>

            <!-- Latest Bill -->
            <div class="bo-widget-bill-cont">
                <div class="bo-bill-info">
                    <span>{{ bt.billtype.last }}</span>
                    <div>
                        <span>{{ bills.amount }} {{ bills.currency}}</span>
                        <p>{{ bills.due_date }}</p>
                    </div>
                </div>
                <div class="bo-bill-actions">
                    <a class="bo-bill-paid-action" href="javascript:;"><i class="fas fa-check"></i></a>
                </div>
            </div>


        </div>
        <div class="bo-see-all">
            <a href="javascript:;">See all bills</a>
        </div>
    </div>
</div>
{% endfor %}

我正在使用 For 循环遍历所有 BillType 对象并使用 {{ bt.billtype.last }} 获取所需数据,以便从模型的相关字段中获取相应的最后一个对象。