Jak poprawnie używać wyszukiwania wstecznego FK w Django, aby wyświetlać instancje modelu potomnego w CBV
Mam dwa modele, jeden z nich wskazuje na drugi jak pokazano poniżej:
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", ...)
Staram się zebrać wszystkie Firmy , które zostały stworzone dla danej Grupy . Więc próbuję uzyskać company_id
(i inne) wartości w Djnago UpdateView
jako listę w szablonie. Mój CBV jest taki, jak pokazano:
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.
Czy ktoś mógłby mi dać znać, jak to działa?
Aktualizacja
Jak wyjaśniono (@Mahmoud Adel), zmodyfikowałem mój, UpdateView
jak pokazano poniżej:
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'])
A potem w szablonie robię:
{{ group.related_grp_company }}
Dzięki temu otrzymuję wynik <app>.Company.None
.
Odpowiedzi
AKTUALIZACJA: Po przetestowaniu na moim lokalnym środowisku env w celu rozwiązania problemów zgłoszonych w komentarzach, to jest ostateczna odpowiedź
Powinieneś zastąpić 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
Zauważ, że kolejność ma znaczenie tutaj w powyższym zapytaniu, zrobienie tego prefetch_related
przed get
naprawi błąd dla 'Group' object has no attribute 'prefetch_related'
.
Możesz również zrezygnować z użycia prefetch_related
i zrobić tylko get
z powyższego zapytania, a to również zadziała, ale prefetch_related
sugeruje się użycie w celu optymalizacji wydajności, ponieważ za każdym razem będziesz pobierać powiązane firmy
Następnie template
możesz po prostu zadzwonić related_grp_company.all
z obiektu, powiedzmy, że przekazujesz bieżący Group
obiekt jako group
szablon, więc powinno być group.related_grp_company.all
, to jest QuerySet
lista, więc zapętl ją lub zrób, co chcesz.
na przykład:
{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}
Ponieważ nie all
dodaliśmy, że otrzymujemy <app>.Company.None
wcześniej
Wskazówka:
related_name
jest używany do odwrotnej relacji , sugerowałbym zmianę jego nazwy na companies
tak, aby była jaśniejsza, na przykład:
group_company = models.ForeignKey(Group, related_name="companies", ...)
więc użycie go później będzie jak group.companies()