2011-09-21 7 views
0

Je suis très nouveau à la programmation et bases de données et j'ai une question sur les étrangers dans django. Dire que j'ai un modèle appelé Expenses qui a une clé étrangère pointée vers le modèle Employees.django modèle foreignkeys question

class Employees(models.Model): 
    ... 

class Expenses(models.Model): 
    ... 
    employee = models.ForeignKey(Employees) 

Je vois que le champ clé étrangère est un ID employé.

Donc ma question est, si, dans la pratique, j'ai un accès à me employee's name sur un formulaire, je dois:

  1. obtenir le employee id de la table Employees avec le nom
  2. Insérez le employee id comme la clé étrangère dans la table des dépenses comme ceci:

    emp_id = Employees.object.get (name = 'John Doe')

    new_expense = Frais ('bar' foo =, ..., employee_id = emp_id.employee_id,) new_expenses.save()

que je fais ce droit? Si oui, est-ce la bonne façon de le faire?

Répondre

2

Les noms de classe de modèle doivent être au singulier. Cela lira beaucoup mieux en Python. Vous pouvez avoir un nom différent pour la table de base de données associée en utilisant class Meta: dans la classe de modèle. En outre, le gestionnaire par défaut est objects, pas object.

Vous n'avez pas besoin de passer par tous ces problèmes. Django prendra en charge les ID de mappage. Il crée un champ "inverse" dans le modèle de destination du ForeignKey. Le nom de cette connexion inverse est le nom du modèle avec ForeignKey plus _set. Donc, dans votre cas, Employees aura un champ généré automatiquement nommé expenses_set qui agit comme un gestionnaire contenant toutes les dépenses de cet employé. Le gestionnaire a également des méthodes telles que create et delete. Ainsi, votre exemple est juste:

new_expense = (Employee.objects.get(name='John Doe') 
    .expense_set.create(foo='bar', ...)) 

Bien qu'il soit préférable de garder un œil sur l'objet Employee:

employee = Employee.objects.get(name='John Doe') 
new_expense = employee.expense_set.create(foo='bar', ...) 

(Pas d'espace autour = lorsqu'il est utilisé dans les listes de paramètres.) Notez que vous n'avez pas besoin pour définir l'ID de l'employé de cette façon.

Cela dit, la plupart d'entre nous fournissent ForeignKey avec un meilleur nom pour ce lien inverse en utilisant le paramètre related_name:

class Expenses(models.Model): 
    ... 
    employee = models.ForeignKey(Employees, related_name='expenses') 

... 
employee = Employee.objects.get(name='John Doe') 
new_expense = employee.expenses.create(foo='bar', ...) 

BTW, si vous voulez obtenir les frais d'un employé, il y a trois façons .L'un est comme ci-dessus:

employee = Employee.objects.get(name='John Doe') 
employee_expenses = employee.expenses.all() 

Ou le one-liner:

employee_expenses = Employee.objects.get(name='John Doe').expenses.all() 

Il y a aussi:

employee_expenses = Expense.objects.filter(employee__name="John Doe") 

Le __ dit à déréférencer le ForeignKey pour se rendre à ses champs. La première façon fait deux requêtes, les autres en font une, mais vous n'obtenez pas l'objet intermédiaire Employee pour une utilisation ultérieure.

+0

Bonne réponse, merci. Je vais essayer quand je rentre à la maison. – zentenk