2010-07-26 5 views
0

Je suis un peu nouveau à Django et j'ai du mal à tirer des tables existantes. J'essaye de tirer des données des colonnes sur plusieurs tables jointes. J'ai trouvé une solution, mais cela ressemble un peu à de la triche et je me demande si ma méthode ci-dessous est considérée comme correcte ou non.Extraire des données de plusieurs tables dans Django

class Sig(models.Model): 
     sig_id = models.IntegerField(primary_key=True) 
     parent = models.ForeignKey('self') 
     state = models.CharField(max_length=2, db_column='state') 
     release_id = models.SmallIntegerField(choices=releaseChoices) 
     name = models.CharField(max_length=255) 
     address = models.CharField(max_length=255, blank=True) 
     city = models.CharField(max_length=255, blank=True) 
     zip = models.CharField(max_length=10, blank=True) 
     phone1 = models.CharField(max_length=255, blank=True) 
     fax = models.CharField(max_length=255, blank=True) 
     email = models.EmailField(max_length=255, blank=True) 
     url = models.URLField(max_length=255, blank=True) 
     description = models.TextField(blank=True) 
     contactname = models.CharField(max_length=255, blank=True) 
     phone2 = models.CharField(max_length=255, blank=True) 
     ratinggroup = models.BooleanField() 
     state_id = models.ForeignKey(State, db_column='state_id') 
     usesigrating = models.BooleanField() 
     major = models.BooleanField() 
     class Meta: 
      db_table = u'sig' 

    class SigCategory(models.Model): 
     sig_category_id = models.IntegerField(primary_key=True) 
     sig = models.ForeignKey(Sig, related_name='sigcategory') 
     category = models.ForeignKey(Category) 
     class Meta: 
      db_table = u'sig_category' 

    class Category(models.Model): 
     category_id = models.SmallIntegerField(primary_key=True) 
     name = models.CharField(max_length=255) 
     release_id = models.SmallIntegerField() 
     class Meta: 
      db_table = u'category' 

Ensuite, ce fut ma solution, qui fonctionne, mais ne se sent pas tout à fait raison:

sigs = Sig.objects.only('sig_id', 'name').extra(
      select = { 
       'category': 'category.name', 
      }, 
     ).filter(
      sigcategory__category__category_id = categoryId, 
      state_id = stateId 
     ).order_by('sigcategory__category__name', 'name') 

Maintenant, puisque les éléments de filtre() rejoindre les modèles sigcategory et catégorie, j'ai pu sortir category.name en utilisant extra(). Est-ce une bonne façon de faire cela? Que faire si je n'ai pas la référence dans filter() et que la jointure n'a pas eu lieu?

Répondre

2

SigCategory a une ForeignKey pointant catégorie, afin que vous puissiez toujours obtenir de l'SigCategory à la catégorie tout simplement en faisant mysigcategory.category (où mysigcategory est votre instance de SigCategory.

Si vous ne l'avez pas accédé précédemment que Par contre, si vous êtes intéressé par l'efficacité de la base de données, regardez select_related

+0

Cependant, si j'essaie de sauter cette relation avec quelque chose comme ceci: sigs [0]. sigcategory.category, je me retrouve avec cette exception: l'objet 'RelatedManager' ha s no attribute 'category' –

+0

C'est parce qu'il peut y avoir plusieurs sigcategories. Ce n'est pas une instance, c'est un gestionnaire. Essayez 'sigs [0] .sigcategory.all() [0] .category' à la place. – Wolph

+1

Je ne peux pas croire que ça m'a échappé. Merci les gars. –

Questions connexes