2016-12-01 3 views
0

I haben die folgenden Modelle:Grouping Reihen mit Bedingung

class Datacomponent(models.Model): 
     id = models.IntegerField(db_column='ID', primary_key=True) # Field name made lowercase. 
     composition = models.ForeignKey(Composition, models.DO_NOTHING, db_column='Composition_ID', null=True, blank=True) # Field name made lowercase. 
     components = models.ForeignKey(Components, models.DO_NOTHING, db_column='Components_ID') # Field name made lowercase. 
     componentvalue = models.FloatField(db_column='ComponentValue') # Field name made lowercase. 



class Components(models.Model): 
    id = models.IntegerField(db_column='ID', primary_key=True) # Field name made lowercase. 
    name = models.CharField(db_column='Name', max_length=45, blank=True, null=True) # Field name made lowercase. 

In Datacomponent gibt es mehrere Reihen von gleicher Zusammensetzung (die Composition Tabelle Fremdschlüssel ist).

Mein Endziel ist es, Composition gesetzt zu bekommen, wenn jeder seiner Komponenten Werte im Bereich einiger Werte sind. In meinem unten gezeigten Ansatz bekomme ich überhaupt keine composition_ids.

CompositionID ComponentID ComponentValue 
    1    1   0.5 
    1    2   0.3 
    2    1   0.6 
    2    2   0.4 
    3    1   0.0 
    3    2   0.1 

So ist die Abfrage für obige Tabelle wäre: ‚Holen Sie sich alle Zusammensetzung ids mit ComponentID = 1 und componentvalue__range = (Minn [a], maxx [b]). Wenn wir den Comp-Wert gte 0,5 für componentID 1 und gte 0,3 für componentID 2 haben möchten, sollte unser Ergebnis nur 2 sein, weil die Komponente 2 von 2 0,6 und der Wert von component2 0,4 ist.

Hier ist mein Ansatz, der nicht funktioniert:

queries = [Q(componentvalue__range = (minn[v], maxx[v]), 
       components__name = "'"+v+"'", 
       ) for v in minn] 

    query = queries.pop() 
    for item in queries: 
     query |= item 

    composition_ids = Datacomponent.objects.filter(query).values_list('composition_id', flat=True) 

    print (composition_ids.count()) 

Antwort

1

Wenn ich Sie richtig verstanden habe, dann so etwas wie dieses

bearbeiten nach Ihren Kommentar helfen können. (Ich hoffe, ich verstehe dich diesmal besser). Sie sind tatsächlich nach Composition Objekte, die sowohl comp1 als auch comp2 innerhalb der angegebenen Bereiche haben (?) Dann können Sie tatsächlich gehen über die Auswahl von Composition Modell.

zuerst ein related_name zu Ihrem composition Feld in Datacomponent Modell, so etwas wie "datacomp", für Reverse-Abfragen hinzufügen.

from django.db.models import Q 

class Datacomponent(models.Model): 
    composition = models.ForeignKey(Composition, related_name='datacomp', ..) 
    ... 

comp_1_query = Q(datacomp__components_id=YOUR_COMP1_ID, datacomp__componentvalue_range=(YOUR_RANGE1_MIN, YOUR_RANGE1_MAX) 
comp_2_query = Q(datacomp__components_id=YOUR_COMP2_ID, datacomp__componentvalue_range=(YOUR_RANGE2_MIN, YOUR_RANGE2_MAX) 


Composition.objects\ 
      .select_related('datacomp')\ # you can for optimization 
      .filter(comp_1_query, comp_2_query)\ # Simply 'and' since you want both to match 
      .values_list('id', 'datacomp__components_id', 'datacomp__componentvalue', flat=True) 

Dies sollte Ihnen die Zusammensetzungen mit component1 und component2 innerhalb der angegebenen Bereiche geben.

+0

Ich denke, Ihre Lösung ist genau das, was ich im OP gezeigt habe. Das Problem hier ist, dass wenn Benutzereingaben (0,5, 0,6) für Komponente1 und (0,2, 0,3) für Komponente2 sowohl Komposition1 als auch Komposition2 im Ergebnis angezeigt werden, da wir mit einem 'oder' kombiniert haben. Das gewünschte Ergebnis ist nur composition1 im Ergebnis zu sein, da es beiden Kriterien entspricht. – javaCity

+0

Ich verstehe jetzt deine Frage besser. Sie sind tatsächlich nach Kompositionen, die sowohl comp1 als auch comp2 in übereinstimmenden Kriterien haben? Bearbeitete die Antwort. –