How to correctly use Django reverse FK lookup to show instances of the child model in CBV

ぃ、小莉子 提交于 2020-12-15 07:02:12

问题


I have two models, field of one of them pointing to the other as shown below:

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

I am trying to get all the Companies that have been created for a particular Group. So I am trying to get the company_id (and other) values in Djnago UpdateView as a list in the template. My CBV is as shown:

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.

Could somebody please let me know how to get this to work?

Update

As explained (@Mahmoud Adel), I have modified my UpdateView as shown below:

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'])

And then in the template, I am doing:

{{ group.related_grp_company }}

With this I am getting an output of <app>.Company.None.


回答1:


UPDATE: After testing on my local env to solve the problems reported in the comments, this is the final answer

You should override 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

Note that order matter here in the above query, doing prefetch_related before get fixes the error for 'Group' object has no attribute 'prefetch_related'.

Also, you can drop using prefetch_related and only do get from the above query and it will work too, but using prefetch_related is suggested to optimize performance as you will fetch the related companies every time

Then at your template you can simply call related_grp_company.all from the object, let's say that you are passing the current Group object as group to your template, so it should like group.related_grp_company.all, this is a QuerySet list, so loop over it or do whatever you want.

for ex:

{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}

Because we didn't add all we were getting<app>.Company.None earlier

Tip:

related_name is used for the reverse relation, I would suggest renaming it to companies so it would be more clearer, for ex:

group_company = models.ForeignKey(Group, related_name="companies", ...)

so using it later will be like group.companies()



来源:https://stackoverflow.com/questions/65057186/how-to-correctly-use-django-reverse-fk-lookup-to-show-instances-of-the-child-mod

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!