2009-08-18 6 views
0

Previously haben sich gefragt, eine genauere Version dieser Frage, aber hatte Schwierigkeiten, artikulieren, was meine Frage war. Bei Nachdenken, das mich zweifeln ließ, ob meine gewählte Lösung für das Problem richtig war, werde ich dieses Mal das Problem erklären und fragen, ob a) ich auf dem richtigen Weg bin und b) ob es einen Weg um meine aktuelle Ziegelmauer herum gibt.Ist eine Viele-zu-viele-Beziehung mit zusätzlichen Feldern das richtige Werkzeug für meinen Job?

Ich baue gerade eine Webschnittstelle, um eine existierende Datenbank von (wenigen) Benutzern abfragen zu können. Das Festhalten an der Analogie von den Doc, ich habe Modelle, die wie folgt aussehen:

class Musician(models.Model): 
    first_name = models.CharField(max_length=50) 
    last_name = models.CharField(max_length=50) 
    dob = models.DateField() 

class Album(models.Model): 
    artist = models.ForeignKey(Musician) 
    name = models.CharField(max_length=100) 

class Instrument(models.Model): 
    artist = models.ForeignKey(Musician) 
    name = models.CharField(max_length=100) 

Wo ich einen Tisch in der Mitte (Musiker) und mehrere Tabellen von zugehörigen Daten, die entweder durch ForeignKey oder OneToOneFields verwandt sind. Benutzer interagieren mit der Datenbank, indem sie Filterkriterien erstellen, um eine Untergruppe von Musikern auf der Grundlage von Daten aus den Haupt- oder verwandten Tabellen auszuwählen. In ähnlicher Weise können die Benutzer dann auswählen, welches Datenelement zum Einstufen von Ergebnissen verwendet wird, die ihnen präsentiert werden. Die Ergebnisse werden dann zunächst als eine zweidimensionale Tabelle mit einer einzelnen Zeile pro Musiker mit ausgewählten Datenfeldern (oder Aggregaten) in jeder Spalte betrachtet.

Um Ihnen eine Vorstellung von Umfang zu geben, hat die Datenbank ~ 5000 Musiker mit ungefähr 20 Feldern verwandter Daten.

Bis hier ist in Ordnung und ich habe eine funktionierende Implementierung. Es ist jedoch wichtig, dass ich für einen bestimmten Benutzer die Möglichkeit habe, eigene Annotationsdatensätze (mehrere) hochzuladen und diese dann auf die gleiche Weise wie die vorhandenen Daten zu filtern und zu ordnen.

So wie ich das versucht hatte, zu tun war, um die Modelle fügen:

class UserDataSets(models.Model): 
    user = models.ForeignKey(User) 
    name = models.CharField(max_length=100) 
    description = models.CharField(max_length=64) 
    results = models.ManyToManyField(Musician, through='UserData') 

class UserData(models.Model): 
    artist = models.ForeignKey(Musician) 
    dataset = models.ForeignKey(UserDataSets) 
    score = models.IntegerField() 

    class Meta: 
     unique_together = (("artist", "dataset"),) 

Ich habe einen einfachen Upload-Mechanismus ermöglichte Benutzer eine Datensatz Datei zu, die zwischen einem Musiker zu 1 Verhältnis von 1 besteht und ihre "Punktzahl". Innerhalb eines gegebenen Benutzerdatensatzes ist jeder Künstler einzigartig, aber unterschiedliche Datensätze sind voneinander unabhängig und enthalten oft Einträge für denselben Musiker.

Dies funktionierte gut für die Anzeige von Daten, von einem bestimmten Künstler beginnend ich so etwas tun kann:

artist = Musician.objects.get(pk=1) 
dataset = UserDataSets.objects.get(pk=5) 
print artist.userdata_set.get(dataset=dataset.pk) 

Doch dieser Ansatz fiel, als ich kam die Filterung und Sortierung des Abfragesatzes implementieren von Musiker basierend auf den Daten in einem einzigen Benutzerdatensatz enthalten. Zum Beispiel könnte ich einfach die Abfrage Satz auf alle Daten in der Userdata Tabelle wie folgt basierend bestellen:

artists = Musician.objects.all().order_by(userdata__score) 

Aber das hilft mir nicht, um die Ergebnisse eines einzelnen Benutzers Datensatzes angegeben. Ebenso muss ich in der Lage sein, die Abfrage basierend auf den "Scores" aus verschiedenen Benutzerdatensätzen zu filtern (zB finde alle Musiker mit einer Punktzahl> 5 in Datensatz1 und < 2 in Datensatz2).

Gibt es eine Möglichkeit, dies zu tun, oder gehe ich die ganze Sache falsch?

Antwort

0

bearbeiten: vergiss es, es ist falsch. Ich werde es behalten, damit Sie lesen können, aber ich werde danach löschen.

Hallo,

Wenn ich richtig verstehe, können Sie so etwas wie dies versuchen:

artists = Musician.objects.select_related('UserDataSets').filter(Q(userdata__score_gt=5, userdata__id=1) | Q(userdata__sorce_lt=2, userdata__id=2) 

Weitere Informationen darüber, wie Q verwenden, überprüfen Sie dies: Complex lookups with Q objects.

Verwandte Themen