如何正确使用 Django 反向 FK 查找在 CBV 中显示子模型的实例
How to correctly use Django reverse FK lookup to show instances of the child model in CBV
我有两个模型,其中一个的字段指向另一个,如下所示:
class Group(models.Model):
group_company_id = models.CharField(primary_key=True, ...)
class Company(models.Model):
company_id = models.CharField(primary_key=True, ...)
group_company = models.ForeignKey(Group, related_name="related_grp_company", ...)
我正在尝试获取为特定 Group 创建的所有 Companies。所以我试图将 Djnago UpdateView
中的 company_id
(和其他)值作为模板中的列表。我的CBV如图:
class GroupCompanyChangeView(UpdateView):
template_name = ...
model = Group
form_class = ...
success_url = reverse_lazy('group_list')
grp_coy_units = Group.objects.prefetch_related('related_grp_company') # I am trying to get the values of `company_id` in the template but nothing is displayed.
有人可以告诉我如何让它工作吗?
更新
正如 (@Mahmoud Adel) 所解释的那样,我修改了我的 UpdateView
,如下所示:
class GroupCompanyChangeView(UpdateView):
template_name = ...
model = Group
form_class = ...
success_url = reverse_lazy('group_list')
def get_object(self, *args, **kwargs):
return Group.objects.get(pk=self.kwargs['pk'])
然后在模板中,我正在做:
{{ group.related_grp_company }}
有了这个,我得到了 <app>.Company.None
的输出。
更新:在我的本地环境上测试解决评论中报告的问题后,这是最终答案
你应该覆盖 get_object()
def get_object(self, *args, **kwargs):
try:
return Group.objects.prefetch_related('related_grp_company').get(pk=self.kwargs['pk'])
except:
return None
请注意上面查询中的顺序很重要,在 get
之前执行 prefetch_related
修复了 'Group' object has no attribute 'prefetch_related'
的错误。
此外,您可以放弃使用 prefetch_related
,仅从上述查询中执行 get
,它也可以工作,但建议使用 prefetch_related
来优化性能,因为您将获取相关公司每次
然后在您的 template
您可以简单地从对象调用 related_grp_company.all
,假设您将当前 Group
对象作为 group
传递给您的模板,所以它应该像 group.related_grp_company.all
,这是一个 QuerySet
列表,所以循环它或做任何你想做的事。
例如:
{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}
因为我们没有添加 all
我们得到 <app>.Company.None
更早
提示:
related_name
用于反向关系,我建议将其重命名为companies
这样会更清楚,例如:
group_company = models.ForeignKey(Group, related_name="companies", ...)
所以以后使用会像group.companies()
我有两个模型,其中一个的字段指向另一个,如下所示:
class Group(models.Model):
group_company_id = models.CharField(primary_key=True, ...)
class Company(models.Model):
company_id = models.CharField(primary_key=True, ...)
group_company = models.ForeignKey(Group, related_name="related_grp_company", ...)
我正在尝试获取为特定 Group 创建的所有 Companies。所以我试图将 Djnago UpdateView
中的 company_id
(和其他)值作为模板中的列表。我的CBV如图:
class GroupCompanyChangeView(UpdateView):
template_name = ...
model = Group
form_class = ...
success_url = reverse_lazy('group_list')
grp_coy_units = Group.objects.prefetch_related('related_grp_company') # I am trying to get the values of `company_id` in the template but nothing is displayed.
有人可以告诉我如何让它工作吗?
更新
正如 (@Mahmoud Adel) 所解释的那样,我修改了我的 UpdateView
,如下所示:
class GroupCompanyChangeView(UpdateView):
template_name = ...
model = Group
form_class = ...
success_url = reverse_lazy('group_list')
def get_object(self, *args, **kwargs):
return Group.objects.get(pk=self.kwargs['pk'])
然后在模板中,我正在做:
{{ group.related_grp_company }}
有了这个,我得到了 <app>.Company.None
的输出。
更新:在我的本地环境上测试解决评论中报告的问题后,这是最终答案
你应该覆盖 get_object()
def get_object(self, *args, **kwargs):
try:
return Group.objects.prefetch_related('related_grp_company').get(pk=self.kwargs['pk'])
except:
return None
请注意上面查询中的顺序很重要,在 get
之前执行 prefetch_related
修复了 'Group' object has no attribute 'prefetch_related'
的错误。
此外,您可以放弃使用 prefetch_related
,仅从上述查询中执行 get
,它也可以工作,但建议使用 prefetch_related
来优化性能,因为您将获取相关公司每次
然后在您的 template
您可以简单地从对象调用 related_grp_company.all
,假设您将当前 Group
对象作为 group
传递给您的模板,所以它应该像 group.related_grp_company.all
,这是一个 QuerySet
列表,所以循环它或做任何你想做的事。
例如:
{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}
因为我们没有添加 all
我们得到 <app>.Company.None
更早
提示:
related_name
用于反向关系,我建议将其重命名为companies
这样会更清楚,例如:
group_company = models.ForeignKey(Group, related_name="companies", ...)
所以以后使用会像group.companies()