Comment utiliser correctement la recherche FK inversée Django pour afficher les instances du modèle enfant dans CBV
J'ai deux modèles, le champ de l'un d'eux pointant vers l'autre comme indiqué ci-dessous:
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", ...)
J'essaye d'obtenir toutes les entreprises qui ont été créées pour un groupe particulier . J'essaie donc d'obtenir les company_id
(et autres) valeurs dans Djnago UpdateView
sous forme de liste dans le modèle. Mon CBV est comme indiqué:
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.
Quelqu'un pourrait-il me faire savoir comment faire fonctionner cela?
Mettre à jour
Comme expliqué (@Mahmoud Adel), j'ai modifié mon UpdateView
comme indiqué ci-dessous:
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'])
Et puis dans le modèle, je fais:
{{ group.related_grp_company }}
Avec cela, je reçois une sortie de <app>.Company.None
.
Réponses
MISE À JOUR: Après avoir testé sur mon environnement local pour résoudre les problèmes signalés dans les commentaires, c'est la réponse finale
Vous devriez remplacer 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
Notez que l'ordre est important ici dans la requête ci-dessus, faire prefetch_related
avant get
corrige l'erreur pour 'Group' object has no attribute 'prefetch_related'
.
En outre, vous pouvez abandonner l'utilisation prefetch_related
et ne faire qu'à get
partir de la requête ci-dessus et cela fonctionnera également, mais l'utilisation prefetch_related
est suggérée pour optimiser les performances, car vous récupérerez les entreprises associées à chaque fois
Ensuite, à votre, template
vous pouvez simplement appeler à related_grp_company.all
partir de l'objet, disons que vous passez l' Group
objet actuel group
à votre modèle, donc il devrait aimer group.related_grp_company.all
, c'est une QuerySet
liste, alors bouclez dessus ou faites ce que vous voulez.
par ex:
{%for d in object.related_grp_company.all%}
<h1>{{ d.company_id }}</h1>
{% endfor %}
Parce que nous n'avons pas ajouté que all
nous devenions <app>.Company.None
plus tôt
Pointe:
related_name
est utilisé pour la relation inverse , je suggérerais de le renommer afin companies
que ce soit plus clair, par exemple:
group_company = models.ForeignKey(Group, related_name="companies", ...)
donc l'utiliser plus tard sera comme group.companies()