So verwenden Sie die Django-Reverse-FK-Suche korrekt, um Instanzen des untergeordneten Modells in CBV anzuzeigen

Nov 28 2020

Ich habe zwei Modelle, von denen eines auf das andere zeigt, wie unten gezeigt:

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

Ich versuche, alle Unternehmen zu ermitteln , die für eine bestimmte Gruppe erstellt wurden . Ich versuche also, die company_id(und andere) Werte in Djnago UpdateViewals Liste in der Vorlage abzurufen . Mein CBV ist wie gezeigt:

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.

Könnte mich bitte jemand wissen lassen, wie das funktioniert?

Aktualisieren

Wie erklärt (@Mahmoud Adel), habe ich meine UpdateViewwie folgt geändert :

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

Und dann mache ich in der Vorlage:

{{ group.related_grp_company }}

Damit bekomme ich eine Ausgabe von <app>.Company.None.

Antworten

MahmoudAdel Nov 29 2020 at 07:39

UPDATE: Nach dem Testen meiner lokalen Umgebung, um die in den Kommentaren gemeldeten Probleme zu lösen, ist dies die endgültige Antwort

Sie sollten überschreiben 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

Beachten Sie, dass die Reihenfolge hier in der obigen Abfrage von Bedeutung ist, prefetch_relatedbevor getder Fehler für behoben wird 'Group' object has no attribute 'prefetch_related'.

Sie können auch die Verwendung der obigen Abfrage löschen und diese prefetch_relatednur getausführen. Dies funktioniert auch. Die Verwendung prefetch_relatedwird jedoch empfohlen, um die Leistung zu optimieren, da Sie jedes Mal die zugehörigen Unternehmen abrufen

Dann können templateSie bei Ihnen einfach related_grp_company.allvom Objekt aus aufrufen . Nehmen wir an, Sie übergeben das aktuelle GroupObjekt groupan Ihre Vorlage. Es sollte group.related_grp_company.allalso eine QuerySetListe sein, also durchlaufen Sie sie oder tun Sie, was Sie wollen.

zum Beispiel:

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

Weil wir nicht hinzugefügt allhaben, wurden wir <app>.Company.Nonefrüher

Trinkgeld:

related_namewird für die umgekehrte Beziehung verwendet , würde ich vorschlagen, sie umzubenennen, companiesdamit sie klarer wird, zum Beispiel:

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

also wird es später so sein group.companies()