DRF:与 unique_together 的一对一关系

发布于 2025-01-11 19:08:14 字数 1196 浏览 0 评论 0原文

我试图了解如何将 OnetoOne 关系与 unique_together 结合使用。目前尝试在我的序列化器和视图中使用它们,但没有成功。

型号:

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,情况不再是这样了。正确的?

第二个问题: 我如何使用这样的模型来返回所有员工及其工作计划,

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

我可以使用外键(没有 unique_together)和嵌套序列化器来做到这一点,但是我无法使用这两个模型来做到这一点多于。

I am trying to understand how to use a OnetoOne relation with unique_together. Currently trying to make use of them in my serializer and view with no success.

Models:

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'),)

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?

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

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

I was able to do this with using a ForeignKey(no unique_together) and a Nested Serializer however i wasn't able to do it with using the two models as they are above.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听,心雨的声音 2025-01-18 19:08:14

第一个问题:由于关系是 OneToOne 如果我没有 unique_together 那么每个员工都可以在 WorkSchedule 中出现一次。然而,由于我有 unique_together,情况不再是这样了。对吗?

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

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

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

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

第二个问题:我如何使用这样的模型来返回所有员工及其工作时间表。

通过使用 ForeignKey。这里使用 OneToOneField 是没有意义的:只有当每个 WorkSchedule 恰好有一个 Employee 并且每个 Employee< 时,这才有意义。 /code>至多有一个WorkSchedule


注意:作为 关于 unique_together [Django-doc] 的文档表示,unique_together 约束可能会被弃用。该文档建议使用 UniqueConstraint [Django-doc] 来自 Django 的 约束
框架

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?

No: a OneToOneField is a ForeignKey with a uniqness constraint. The fact that you later define an extra constraint does not matter. This thus means that your unique_together has no impact: since the OneToOneField already guarantees that the employee is unique, this implies that the combination with the workday will be unique, even without specifying a unique_together.

You thus should thus use a ForeignKey, so:

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

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

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

By using a ForeignKey. It make no sense here to use a OneToOneField: this only makes sense if each WorkSchedule has exactly one Employee, and each Employee has at most one 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
.

梦过后 2025-01-18 19:08:14

尝试理解“唯一” -

代码示例 -

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. 如果任何其他对象中的员工值为A,则工作日不得为A。否则,它将在唯一在一起约束时失败。

  2. 同样,如果任何其他对象中的工作日值为A,则员工不能为A,否则,它将再次在唯一的共同约束下失败。

回到你的问题 -

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

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

文档中还提到 unique_together 将来将会贬值,因此您必须按照 @Willem Van Onsem 先生提到的方式进行编码。

Trying to understand unique together -

Code example -

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

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

Unique together here means every object of WorkSchedule will be unique when you compare considering two fields at a time.

Eg.- suppose first object is

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

Now no other object can have values employee = A and workday = A combined.

So other objects can have values such as (2 cases) -

  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.

Coming back to your question -

since you have used OneToOneField for employee in WorkSchedule, so by default there will be no two same values of employee and you can neglect using unique_together.

But again the result which you are expecting, will create two objects of WorkSchedule (from the result example) with the same employee and different workday. So you can not use OneToOneField, you will have to use ForeignKey for employee and make sure employee and workday are unique together.

It is also mentioned in the documentation that unique_together will be depreciated in the future, so you will have to code as mentioned by sir @Willem Van Onsem.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文