2009-08-18 9 views
0

Previously a essayé de poser une version plus spécifique de cette question, mais a eu du mal à articuler ma question. À la réflexion, cela m'a fait douter que la solution choisie corresponde bien au problème. Cette fois, je vais expliquer le problème et demander si a) je suis sur la bonne voie et b) s'il y a un moyen de contourner mon mur de briques actuel.Une relation plusieurs-à-plusieurs avec des champs supplémentaires est-elle le bon outil pour mon travail?

Je suis en train de construire une interface web pour permettre à une base de données existante d'être interrogée par (un petit nombre) d'utilisateurs. L'analogie avec le collage des docs, j'ai des modèles qui ressemblent à ceci:

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) 

Là où j'ai une table centrale (Musician) et plusieurs tables de données associées qui sont liés soit par ForeignKey ou OneToOneFields. Les utilisateurs interagissent avec la base de données en créant des critères de filtrage pour sélectionner un sous-ensemble de musiciens sur la base des données les données sur les tables principales ou connexes. De même, les utilisateurs peuvent sélectionner quelle donnée est utilisée pour classer les résultats qui leur sont présentés. Les résultats sont ensuite visualisés initialement sous la forme d'un tableau à deux dimensions avec une seule ligne par musicien avec des champs de données sélectionnés (ou des agrégats) dans chaque colonne. Pour vous donner une idée de l'échelle, la base de données compte environ 5 000 musiciens avec une vingtaine de champs de données connexes.

Jusqu'à ici est très bien et j'ai une mise en œuvre de travail. Cependant, il est important que j'ai la possibilité pour un utilisateur donné de télécharger ses propres ensembles de données d'annotations (plus d'un), puis de les filtrer et de les ordonner de la même manière qu'avec les données existantes.

La façon dont je l'avais essayé de le faire était d'ajouter les modèles:

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

J'ai un mécanisme simple de téléchargement permettant aux utilisateurs de télécharger un fichier de jeu de données qui se compose de 1 à 1 relation entre un musicien et leur "score". Dans un ensemble de données utilisateur donné, chaque artiste sera unique, mais les différents ensembles de données sont indépendants les uns des autres et contiendront souvent des entrées pour le même musicien.

Cela a bien fonctionné pour afficher les données, à partir d'un artiste donné, je peux faire quelque chose comme ceci:

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

Cependant, cette approche est tombée sur le moment où je suis arrivé à mettre en œuvre le filtrage et la commande de requête ensemble de musiciens sur la base des données contenues dans un seul jeu de données utilisateur. Par exemple, je pourrais facilement commander l'ensemble de requête basée sur l'ensemble des données de la table UserData comme ceci:

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

Mais cela ne me permet pas pour les résultats d'un ensemble de données unique utilisateur donné. De même, je dois être capable de filtrer l'ensemble de requêtes en fonction des "scores" de différents ensembles de données utilisateur (par exemple, trouver tous les musiciens avec un score> 5 dans dataset1 et < 2 dans dataset2).

Y a-t-il un moyen de le faire, ou est-ce que je vais mal?

Répondre

0

éditer: nevermind, c'est faux. Je vais le garder pour que vous puissiez le lire, mais je le supprimerai ensuite.

Salut,

Si je comprends bien, vous pouvez essayer quelque chose comme ceci:

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

Pour plus d'informations sur l'utilisation de Q, vérifier: Complex lookups with Q objects.

Questions connexes