Django ORM - 我可以使用 ID 以外的其他列创建具有外键的新对象吗?

Posted

技术标签:

【中文标题】Django ORM - 我可以使用 ID 以外的其他列创建具有外键的新对象吗?【英文标题】:Django ORM - Can I create a new object with a foreign key using a different column other than ID? 【发布时间】:2021-01-16 19:13:46 【问题描述】:

我检查了一下,找不到任何我正在寻找的示例,所以我不确定它是否可能。

我有一个带有外键的模型。我想在该模型中创建一个新对象,但我没有 ID,但我有字段“用户名”值。我还应该补充一点,这是与另一个外键的外键关系

WeekdayAssignment 模型示例:

class WeekdayAssignment(models.Model):
    start_date = models.DateField(auto_now=False, auto_now_add=False)
    end_date = models.DateField(auto_now=False, auto_now_add=False)
    triage = models.ForeignKey(TeamMember, on_delete=models.PROTECT, related_name="triagers")
    ...

团队成员模型示例:

class TeamMember(models.Model):
    member = models.ForeignKey(User, on_delete=models.PROTECT, verbose_name='Member Name')
    ...

用户模型示例:

class User(models.Model):
    first_name = models.CharField(max_length=50)
    last_name = models.CharField(max_length=50)
    username = models.CharField(max_length=50)

我想做的是使用来自外键的成员用户名创建一个新对象,而不是像这样的 ID:

WeekdayAssignment.objects.create(start_date='2021-01-13', end_date='2021-01-20', triage__member__username='jac')

但是,如果我这样做,我会收到错误 WeekdayAssignment() got an unexpected keyword argument 'triage__member__username',如果我删除 __username

如果像这样从字段中删除 __member__username

WeekdayAssignment.objects.create(start_date='2021-01-13', end_date='2021-01-20', triage='jac')

我得到ValueError:无法分配“'jac'”:“WeekdayAssignment.triage”必须是“TeamMember”实例。这是完全可以预料的,因为它不是 ID 或实例。 p>

所以我的问题是,我是否可以使用外键模型中的另一个字段来创建数据,还是我使用 ID 卡住了?

任何帮助将不胜感激。

谢谢, jAC

【问题讨论】:

可以直接在该字段中添加任何TeamMember 实例,但它必须是TeamMember 实例。 【参考方案1】:

您需要提供TeamMember 的实例。因此,假设用户名为“Jac”的用户登录:

以下方法错误:

wdass = WeekdayAssignment.objects.create(start_date='2021-01-13', end_date='2021-01-20', triage='Jac')

下面的方法是对的:

t_member = TeamMember.objects.filter(member=request.user).first()
wdass = WeekdayAssignment.objects.create(start_date='2021-01-13', end_date='2021-01-20', triage=t_member.id)

【讨论】:

这实际上比我根据下面的评论最终做的更好。我进行了轻微的编辑并将其 t-member 更改为 TeamMember.objects.get(member=request.user)。但这就是我要找的!谢谢!【参考方案2】:

不,你不能。在底层,Django 的 create 查询集方法使用INSERT SQL 语句在相应的数据库表中创建一个新行。 ForeignKey 字段对应于一个整数 DB 列(通常),它包含对数据库中另一个表中的行的引用。因此,对于 Django ORM,您需要提供一个数字 ID 或代表您的 ForeignKey 的模型实例。如果您没有 ID 但有另一个字段值,那么首先您需要通过该字段进行另一个查询以找到具有此值的模型实例(数据库行)并使用此模型实例(或其行 ID)在您的create 电话中。

【讨论】:

啊,完全有道理。非常感谢!对于其他正在寻找解决方法的人,我最终对用户进行了获取,然后使用该结果对成员进行了获取。

以上是关于Django ORM - 我可以使用 ID 以外的其他列创建具有外键的新对象吗?的主要内容,如果未能解决你的问题,请参考以下文章

我可以在 django 1.3 的 orm 中控制 GROUP BY 吗?

如何解析在 DB 上使用 SQL 脚本生成的 ID (Django ORM)

Django ORM:未继承子级的字段和值。对象重复。 (使用Django管理界面)

使用 django ORM 获取只有最新孩子的父母的优化方式

使用 Django ORM 进行选择性事务管理

使用 Django ORM 中的列过滤器获取主键 ID