Django模型外键问题
我刚开始学习编程和数据库,有个关于Django中外键的问题。
假设我有一个叫做 Expenses
的模型,它有一个外键指向 Employees
模型。
class Employees(models.Model):
...
class Expenses(models.Model):
...
employee = models.ForeignKey(Employees)
我看到这个外键字段是员工的ID。
所以我的问题是,如果在实际操作中我在一个表单上能看到 员工的名字
,我需要:
- 从
Employees
表中根据名字获取员工ID
然后把这个
员工ID
作为外键插入到Expenses
表中,像这样:emp_id = Employees.object.get(name = 'John Doe')
new_expense = Expenses(foo = 'bar', ..., employee_id = emp_id.employee_id,)
new_expenses.save()
我这样做对吗?如果对的话,这样做是正确的吗?
1 个回答
模型类的名字应该用单数形式,这样在Python中看起来更顺眼。你可以通过在模型类里面使用 class Meta:
来让关联的数据库表有不同的名字。而且,默认的管理器是 objects
,而不是 object
。
其实你不需要费那么大劲。Django会自动处理ID的映射。它会在目标模型中创建一个“反向”字段,和 ForeignKey
相关联。这个反向连接的名字是带有ForeignKey的模型名字加上 _set
。所以在你的例子中,Employees
会自动生成一个叫 expenses_set
的字段,这个字段就像一个管理器,里面包含了所有这个员工的开支。这个管理器还有一些方法,比如 create
和 delete
。所以你的例子其实就是:
new_expense = (Employee.objects.get(name='John Doe')
.expense_set.create(foo='bar', ...))
不过最好还是关注一下 Employee
对象:
employee = Employee.objects.get(name='John Doe')
new_expense = employee.expense_set.create(foo='bar', ...)
(在参数列表中使用 =
时,周围不要有空格。)要注意,你不需要用这种方式来设置员工ID。
话说回来,我们大多数人会通过使用 related_name
参数给 ForeignKey
提供一个更好的名字来表示那个反向链接:
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', ...)
顺便说一下,如果你想获取某个员工的开支,有三种方法。第一种就像上面那样:
employee = Employee.objects.get(name='John Doe')
employee_expenses = employee.expenses.all()
或者你可以用一行代码:
employee_expenses = Employee.objects.get(name='John Doe').expenses.all()
还有一种方法是:
employee_expenses = Expense.objects.filter(employee__name="John Doe")
这里的 __
表示要解引用ForeignKey,以便访问它的字段。第一种方法会进行两次查询,而其他方法只需一次,但你不能在后面使用中间的 Employee
对象。