Comment utiliser correctement la recherche FK inversée Django pour afficher les instances du modèle enfant dans CBV

Nov 28 2020

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 UpdateViewsous 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 UpdateViewcomme 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

MahmoudAdel Nov 29 2020 at 07:39

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_relatedavant getcorrige l'erreur pour 'Group' object has no attribute 'prefetch_related'.

En outre, vous pouvez abandonner l'utilisation prefetch_relatedet ne faire qu'à getpartir de la requête ci-dessus et cela fonctionnera également, mais l'utilisation prefetch_relatedest suggérée pour optimiser les performances, car vous récupérerez les entreprises associées à chaque fois

Ensuite, à votre, templatevous pouvez simplement appeler à related_grp_company.allpartir de l'objet, disons que vous passez l' Groupobjet actuel groupà votre modèle, donc il devrait aimer group.related_grp_company.all, c'est une QuerySetliste, 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 allnous devenions <app>.Company.Noneplus tôt

Pointe:

related_nameest utilisé pour la relation inverse , je suggérerais de le renommer afin companiesque ce soit plus clair, par exemple:

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

donc l'utiliser plus tard sera comme group.companies()