Como usar corretamente a pesquisa FK reversa do Django para mostrar instâncias do modelo filho em CBV
Tenho dois modelos, campo de um deles apontando para o outro conforme mostrado abaixo:
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", ...)
Estou tentando obter todas as empresas que foram criadas para um determinado grupo . Portanto, estou tentando obter os company_id
(e outros) valores em Djnago UpdateView
como uma lista no modelo. Meu CBV é como mostrado:
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.
Alguém poderia me dizer como fazer isso funcionar?
Atualizar
Conforme explicado (@Mahmoud Adel), eu modifiquei meu UpdateView
conforme mostrado abaixo:
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'])
E então, no modelo, estou fazendo:
{{ group.related_grp_company }}
Com isso, estou obtendo uma saída de <app>.Company.None
.
Respostas
ATUALIZAÇÃO: Depois de testar em meu ambiente local para resolver os problemas relatados nos comentários, esta é a resposta final
Você deve substituir 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
Observe que o pedido é importante aqui na consulta acima, fazer o prefetch_related
before get
corrige o erro para 'Group' object has no attribute 'prefetch_related'
.
Além disso, você pode deixar de usar prefetch_related
e apenas fazer get
da consulta acima e funcionará também, mas o uso prefetch_related
é sugerido para otimizar o desempenho, pois você buscará as empresas relacionadas todas as vezes
Em seguida, template
você pode simplesmente chamar related_grp_company.all
do objeto, digamos que você está passando o Group
objeto atual como group
para o seu modelo, então deve gostar group.related_grp_company.all
, esta é uma QuerySet
lista, então faça um loop sobre ela ou faça o que quiser.
por ex:
{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}
Porque não adicionar all
estávamos recebendo <app>.Company.None
mais cedo
Dica:
related_name
é usado para a relação reversa , sugiro renomeá-lo para companies
assim ficar mais claro, por ex:
group_company = models.ForeignKey(Group, related_name="companies", ...)
então usá-lo mais tarde será como group.companies()