Django从父对象访问模板中的子数据

Posted

技术标签:

【中文标题】Django从父对象访问模板中的子数据【英文标题】:Django Accessing Child Data in Templates from Parent object 【发布时间】:2021-10-16 09:21:48 【问题描述】:

我是 Django 新手,正在尝试做一些应该非常简单的事情(在我看来),但我已经花了几个小时在这上面,但还没有解决它。

目标:在模板中,我想使用父对象从子对象的字段中获取值。在这种情况下,我试图通过知道父 sample 来获取 lab_request 对象。

到目前为止,我已经尝试在 Lab_Request 模型中同时使用 ForeignKeyOneToOneField

我认为我出错的代码中的特定区域是 sample.lab_request.placeholder_to_be_replaced Sample 是父母,“Lab_Requests”是孩子。在这种情况下,我已将其设置为 OneToOneField,但实际上我在另一个领域遇到了这个问题,它将成为多个孩子的父母。

代码:

#models.py

class Sample(models.Model):

    order = models.ForeignKey(Order, on_delete=models.CASCADE)
   status = models.CharField(max_length=2, choices=SAMPLE_STATUS_OPTIONS, default="01")
    sample_number = models.CharField(max_length=19, unique=True, editable=False, default=get_sample_number)



class Inspection_Request(models.Model):
    #Add stuff here
    placeholder_to_be_replaced = models.CharField(max_length=1)
    sample = models.OneToOneField(Sample, on_delete=models.CASCADE)
    inspector = models.OneToOneField(Inspector, on_delete=models.CASCADE, null=True, blank=True)


class Lab_Request(models.Model):
    #Add stuff here
    placeholder_to_be_replaced = models.CharField(max_length=1)
    sample = models.OneToOneField(Sample, on_delete=models.CASCADE)
    inspector = models.OneToOneField(Inspector, on_delete=models.CASCADE, null=True, blank=True)

#views.py

class SampleHomeView(ListView):
    model = Sample
    samples = Sample.objects.all
    context_object_name = 'samples'
    template_name = '<app name>/sample.html'
    ordering = ['-sample_date']
    paginate_by = 10

#sample.html

% extends 'base.html' %
% block content %
% load custom_tags %
% load define_action %
<h1>Sample Status</h1>

#other stuff that doesn't matter

            % for sample in samples %
                % if user.profile.employee.pk == sample.inspector.employee.pk or perms.ics.view_sample %
                                    <tr>
                                        <td class="column1"> sample.sample_date </td>
                                        <td class="column2"> sample.status|sample_status_options </td>
                                        <td class="column3"><a href="#"> sample.sample_number </a></td>
                                        <td class="column4"><a href="#"> sample.order.customer.customer_name </a></td>
                                        <td class="column5"><a href="#"> sample.lab_request.placeholder_to_be_replaced  sample.lab_request.lab.lab_name  sample.inspection_request.inspector.employee.employee_first_name </a></td>
                                        <td class="column6"> sample.date_modified|date:'F d, Y'  </td>
                                    </tr>
                % endif %
            % endfor %


#more stuff that doesn't matter

% block table %
% endblock table %

% endblock content %

任何指导将不胜感激。

【问题讨论】:

你能展示Lab_Requests的模型吗? 也是samples = Sample.objects.all,应该是Sample.objects.all() 对(缺少括号) @bdbd 我添加了另一个与 Inspection_Request 模型基本相同的模型。 您使用lab_request 的方式看起来不错。什么不工作?你有错误吗? @bdbd 不,我没有收到任何错误。当我在 shell 中时,我可以从 lab_request 对象转到示例对象,但不能相反。我什至刷新了数据库,以防出现一些构建错误并且它没有变化。好像关系只有一个方向。我觉得这一定是我错过了一些愚蠢的东西,但我只是不知道。 【参考方案1】:

好的,我想通了。我需要把孩子叫给父母,这与我做的有点不同。我需要使用 sample.lab_request_set.all.0.lab 而不是 sample.lab_request.lab

对于将来需要此功能的任何人,如果您没有在 ForeignKey 中设置相关名称,那么它将是 parent_model_name.child_model_name_set。所有这将为您提供一个查询集,然后您可以迭代或只选择第一个就像我在 .all 末尾对 .0 所做的那样。这适用于模板。如果您在 python 文件中需要它,那么您将使用 parent_model_name.child_model_name_set.all() 调用该函数

【讨论】:

您在问题中使用了一对一的字段,所以sample.lab_request.placeholder_to_be_replaced 是正确的 @bdbd 感谢您的提醒。我让它在 python shell 中工作,但由于某种原因它不会在我的 Django 模板中。我最终将其切换回 ForeignKey 关系以使其正常工作。不知道为什么我的代码没有像所写的那样使用 OneToOne 关系,但现在可以了。

以上是关于Django从父对象访问模板中的子数据的主要内容,如果未能解决你的问题,请参考以下文章

在 PyQt 的子窗口中从父窗口访问数据

Django 管理模板:访问模板中的请求对象

访问 ng-container 中的子组件变量

Angular ui-router - 如何访问从父模板传递的嵌套命名视图中的参数?

Django - 模板对象访问详细名称

我可以访问 Django 模板列表中第一个对象的属性吗?