DRF:与 unique_together 的一对一关系

DRF: OneToOne relation with unique_together

我正在尝试了解如何使用 unique_together 的 OnetoOne 关系。目前正尝试在我的序列化程序中使用它们,但没有成功查看。

型号:

class Employees(models.Model):
    name = models.CharField()
    position = models.CharField()
    phone = models.IntegerField()


class WorkSchedule(models.Model):
    employee = models.OneToOneField('Employees')
    workday = models.DateTimeField()

    class Meta:
        unique_together = (('employee', 'workday'),)

第一个问题: 由于关系是 OneToOne 如果我没有 unique_together 那么每个员工都可以出现在 WorkSchedule 中一次。但是,由于我有 unique_together,情况已不再如此。正确吗?

第二个问题: 我将如何使用这样的模型 return 所有员工和他们这样的工作时间表

{
    "employees": [
        {
            "employee": "John",
            "workschedule": [
                {
                    workday: "2022-03-03"
                },
                {
                    workday: "2022-03-04"
                }
        },
        {
        
            "employee": "Tom",
            "workschedule": [
                {
                    workday: "2022-03-03"
                },
                {
                    workday: "2022-03-04"
                }
        }
}

我可以使用 ForeignKey(没有 unique_together)和 Nested Serializer 来做到这一点,但是我无法使用上面的两个模型来做到这一点。

First question: Since the relation is OneToOne if i didn't have unique_together then each employee could appear in WorkSchedule once. However since i have unique_together this is not the case anymore. Correct?

OneToOneField 是具有唯一性约束的ForeignKey。您稍后定义额外约束的事实无关紧要。因此,这意味着您的 unique_together 没有影响:由于 OneToOneField 已经保证 employee 是唯一的,这意味着与 workday 的组合将是唯一的,即使没有指定 unique_together.

因此您应该使用 ForeignKey,所以:

class WorkSchedule(models.Model):
    employee = models.<strong>ForeignKey(</strong>'Employees', on_delete=models.CASCADE<strong>)</strong>
    workday = models.DateTimeField()

    class Meta:
        constraints = [
            models.<strong>UniqueConstraint(</strong>fields=['employee', 'workday'], name='unique_employee_workday'<strong>)</strong>
        ]

Second Question: How would i use such models to return all employees and their workschedules like this.

通过使用 ForeignKey。这里使用 OneToOneField 是没有意义的:这只有在每个 WorkSchedule 恰好有一个 Employee 并且每个 Employee 最多有 时才有意义一个WorkSchedule.


Note: As the documentation on unique_together [Django-doc] says, the unique_together constraint will likely become deprecated. The documentation advises to use the UniqueConstraint [Django-doc] from Django's constraint framework.

一起努力了解unique -

代码示例-

class WorkSchedule(models.Model):
    employee = models.CharField()
    workday = models.CharField()

    class Meta:
        unique_together = (('employee', 'workday'),)

此处的唯一在一起意味着当您同时考虑两个字段进行比较时,WorkSchedule 的每个对象都是唯一的。

例如-假设第一个对象是

{
    "employee" : "A"
    "workday" : "A"
}

现在没有其他对象可以有值 employee = Aworkday = A 合并.

因此其他对象可以具有诸如(2 例)-

的值
  1. If employee value is A in any other object, workday must not be A. Otherwise, it will fail at unique together constrain.

  2. Same, if the workday value is A in any other object, the employee can not be A, Otherwise, it will again fail at unique together constrain.

回到你的问题 -

由于您在 WorkSchedule 中为 employee 使用了 OneToOneField,因此默认情况下会有没有两个相同的 employee 值,你可以忽略使用 unique_together.

但同样是您所期望的结果,将创建两个 WorkSchedule 对象(来自结果示例)相同的员工不同的工作日。所以你不能使用 OneToOneField,你必须为员工使用 ForeignKey 并确保员工和工作日一起是唯一的。

文档中还提到unique_together以后会贬值,所以你得按照@Willem Van Onsem先生说的编码。