2017-03-28 1 views
1

Je suis un débutant sur Django et un peu plus avancé sur Python. Je suis complètement étonné par Django et je joue avec ça depuis une semaine maintenant. J'ai regardé beaucoup de tutoriels et de questions/réponses stackoverflow et j'ai découvert beaucoup de choses.Utiliser plusieurs clés étrangères

Cependant, je suis encore un peu perdu en ce qui concerne les relations OneToMany/Foreign Key et la façon d'y accéder. J'ai jeté un coup d'oeil à l'exemple "Bibliothèque/Livre" de la documentation officielle mais j'essaie toujours de comprendre comment résoudre le problème ci-dessous.

[Explications]

  • J'ai des utilisateurs (déjà créé)
  • Pour les utilisateurs Django-construit, j'ai ajouté un profil (OneToOneField)
  • Le profil ne contient qu'un seul élément pour chaque utilisateur: un titre (clé étrangère)
  • Le titre provient à son tour d'une liste existante de titres disponibles
  • Enfin, j'ai l'occasion (une classe) qui a un utilisateur lié (clé étrangère)

dans models.py

class ProfileStatus(models.Model): 
    """ table of available titles for users """ 
    status = models.CharField(max_length=100) 
    def __str__(self): 
     return self.status 

class Profile(models.Model): 
    """ add a title to an existing user """ 
    user = models.OneToOneField(User, on_delete=models.CASCADE) 
    title = models.ForeignKey(ProfileStatus, on_delete=models.CASCADE) 

class OpportunityStatus(models.Model): 
    """ status for an opportunity """ 
    status = models.CharField(max_length=100) 
    def __str__(self): 
     return self.status 

class Opportunity(models.Model): 
    """ An opportunity """ 
    name = models.CharField(max_length=100, default='') 
    director = models.ForeignKey(User, on_delete=models.CASCADE) 
    status = models.ForeignKey(OpportunityStatus, on_delete=models.CASCADE) 

    def __str__(self): 
     return self.name 

[Qu'est-ce que je cherche]

Je voudrais savoir comment vous:

  • pour les utilisateurs havin g 'Director' comme titre
  • puis de la liste des opportunités où ils sont liés en tant que directeur
  • puis de filtrer cette liste aux opportunités qui ont le statut 'alive' pour être ensuite passées à une vue (que je peux gérer)

Répondre

0

Généralement, vous utilisez la syntaxe double-underscore pour suivre les relations. Ainsi, par exemple, pour obtenir les utilisateurs qui ont le titre de directeur, vous feriez:

User.objects.filter(profile__title__status='Director') 

Cependant, si vous voulez opportunités plutôt que les utilisateurs, vous devez commencer par le modèle d'opportunité. Donc:

Opportunity.objects.filter(status__status='alive', director__profile__title__status='Director') 

Cette requête peut être légèrement moins horrible si vous avez fait pointer l'option Opportunité sur Profil plutôt que sur Utilisateur.

+0

Génial, la deuxième option est exactement ce que j'ai désespérément recherché (__director__profile__title_status ...)! Le status = 'alive' doit cependant être status = ID plutôt que le mot-clé, avez-vous une idée de la façon dont je pourrais avoir status = 'alive' plutôt que status = ID? Merci beaucoup pour votre aide! Malheureusement je ne peux pas voter parce que je suis nouveau sur Stack mais dès que j'en aurai assez, je reviendrai voter pour ça :) – ArokK

+0

Je l'ai mis à jour, ça aurait du être 'status__status'. Vous pourriez penser aux noms un peu plus, il est déroutant d'avoir une clé étrangère nommée comme le champ réel dans le modèle de destination. Peut-être que OpportunityStatus et ProfileStatus devraient avoir des champs 'name' plutôt que' status'. –

+0

Oui, en effet, vous avez complètement raison sur les noms - c'est déroutant. Tout a trié, merci !! – ArokK