DjangoリバースFKルックアップを正しく使用して、CBVで子モデルのインスタンスを表示する方法

Nov 28 2020

私には2つのモデルがあり、以下に示すように、一方のフィールドがもう一方を指しています。

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", ...)

特定のグループ用に作成されたすべての会社を取得しようとしています。そのため、Djnagoの(およびその他の)値をテンプレートのリストとして取得しようとしています。私のCBVは次のとおりです。company_idUpdateView

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

回答

MahmoudAdel Nov 29 2020 at 07:39

更新:コメントで報告された問題を解決するためにローカル環境でテストした後、これが最終的な答えです

オーバーライドする必要があります 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

上記のクエリでは順序が重要であることに注意してください。prefetch_related前に実行getすると、のエラーが修正され'Group' object has no attribute 'prefetch_related'ます。

また、を使用してドロップすることができ、上記のクエリからprefetch_relatedのみ実行できgetます。これもprefetch_related機能しますが、毎回関連する会社を取得するため、パフォーマンスを最適化するために使用することをお勧めします

次に、オブジェクトからtemplate簡単に呼び出すことができます。related_grp_company.allたとえば、テンプレートに関して現在のGroupオブジェクトを渡しているとしましょう。これはリストであるため、ループするか、必要な操作を実行します。groupgroup.related_grp_company.allQuerySet

例:

{%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()