2016-04-25 8 views
1

Ich habe eine Ansicht, die ein bestimmtes Modell zur Liste (lässt es class A nennen), wie folgt aus:Django ORM: ein Listview, anpassen und weitere Informationen zu seiner queryset hinzufügen

class BaseListView(ListView, MultipleObjectMixin): 
    http_method_names = ['get'] 
    order_field = None 

    def get_paginate_by(self, queryset): 
     session_manager = SessionManager(self.request.session) 
     return session_manager.paginate_by.get() 

    def get_context_data(self, **kwargs): 
     context = super(BaseListView, self).get_context_data(**kwargs) 

     session_manager = SessionManager(self.request.session) 
     session_manager.paginate_by.set_to(context) 

     return context 

Diese Ansicht hat genau das, was gebraucht wurde , bis jetzt. Jetzt muss ich die Liste der Objekte, die es abruft, mit einer anderen Liste von Objekten vergleichen (class B). Die Objekte der Klassen A und B haben beide einen Primärschlüssel mit ihrem Namen.

Ich möchte überprüfen, ob eines der Objekte von class A hat die gleiche name (Primärschlüssel) als eines der Objekte in class B. Wenn es eine Instanz von A in B gibt, möchte ich einen bestimmten Parameter oder etwas wie is_in_B=True hinzufügen.

Ich brauche das, damit ich diese Instanzen von A auf eine andere Weise in der Vorlage darstellen kann.

Wie könnte ich das tun?

Dies ist, was ich von mir selbst mit für den Moment gekommen sind:

class AListView(BaseListView): 
    model = "A" 

    def get_queryset(self): 
     queryset = super(AListView, self). get_query_set() 

     all_objects_A = A.objects.all() 
     all_objects_B = B.objects.all() 

     # modify queryset to indicate which instances of A are present in B 
     # No idea how to do this 

     return queryset 

Ich bin nicht wirklich sicher, dass dies ein sachgemäßer Ansatz.

Auch, wie bin ich die queryset von meiner Klasse zurück ändern soll, damit ich name als eine der Instanzen von class B die gleichen, die Instanzen von class A Aktien zeigen kann?

+0

Sind 'A' und' B' überhaupt verwandt? – Sayse

+0

'A's Primärschlüssel ist das Feld' name' (Beispiel: "John Doe"). 'B's Primärschlüssel ist auch das Feld' name' (Beispiel. '' Jane Doe "). Also möchte ich in der Lage sein zu wissen, ob es" John Doe "in der Liste der' B' Objekte gibt und zurückkomme Diese Information im Abfrage-Set. – Xar

Antwort

1

Sie können annotate your queryset with a conditional expression dies zu erreichen:

from django.db.models import Case, When, Value 

def get_queryset(self): 
    # This gives you the queryset of A objects 
    queryset = super(AListView, self).get_queryset() 
    # List of primary keys of B objects 
    all_objects_B = B.objects.all().values_list('pk',flat=True) 

    # modify queryset to indicate which instances of A are present in B 
    return queryset.annotate(
     is_in_b=Case(When(pk__in=all_objects_B, then=Value(True)), 
         default=Value(False)) 
     ) 
    ) 

Ihre queryset Objekte wird nun eine is_in_b Eigenschaft.

Dies funktioniert gut, wenn Ihre Liste der B-Objekte klein ist. Wenn es groß ist, bin ich mir nicht sicher, ob es sehr effizient ist, und Sie müssen es möglicherweise weiter entwickeln, um zu sehen, ob die Überprüfung (ist A in B) direkt in der Datenbank durchgeführt werden kann (möglicherweise erfordert Raw SQL).

+0

Perfekt! Vielen Dank @solarissmoke – Xar