首页 > 解决方案 > Django ORM - 使用用户外键更新特定实例

问题描述

我有以下模型设置:

class Model1(models.Model):
    val1_1 = models.CharField(max_length=25, blank=True)
    val1_2 = models.CharField(max_length=25, blank=True)
    user = models.ForeignKey('users.User', on_delete=models.PROTECT, related_name='model1')

class Model2(models.Model):
    val2_1 = models.BinaryField()
    model1_link = models.ForeignKey(Case, on_delete=models.CASCADE, related_name='model2')

class Model3(models.Model):
    id = models.BigAutoField(primary_key=True)
    model2_link = models.ForeignKey(Model2, on_delete=models.CASCADE, related_name='model3')
    val3_1 = models.CharField(max_length=50)

class Model4(models.Model):
    id = models.BigAutoField(primary_key=True)
    model3_link = models.ForeignKey(Model3, on_delete=models.CASCADE, related_name='model4', null=True, default=None)
    pred = models.CharField(max_length=50)

    # These fields are NOT FILLED IN during creation of an instance, and are instead updated later on with a separate query
    disputed_on = models.DateTimeField(blank=True, null=True)
    suggested_by = models.ForeignKey('users.User', on_delete=models.PROTECT, related_name='submitted_disputes', blank=True, null=True)

有时,我会想要访问 Model4 的特定实例,通过从 Model1 一路遍历来实际填写字段有争议的_on 和建议的_by 中的值。我目前这样做:

query = Model1.objects.filter(id=some_chosen_id).get().model2.last().model3.filter(val3_1=some_chosen_value).get().model4.last()

该查询的输出是单个模型实例,而不是 QuerySet。接下来,我计算要插入的新值:

dispute_date = datetime.now(tz.tzutc())

if request.user.is_authenticated:
    disputer = request.user
else:
    # Assume admin (first entry)
    disputer = User.objects.get(pk=1)

我通过执行以下操作保存新值:

query.disputed_on = dispute_date
query.suggested_by = disputer

query.save()

现在,最奇怪的事情发生了——我的 postgres DB 给了我一个错误说明,如下:

postgres_1  | 2020-03-30 11:45:31.700 AEDT [4169] ERROR:  duplicate key value violates unique constraint "users_user_username_key"

现在,按照我的阅读方式,调用 prediction.save() 也会导致数据库尝试更新用户表。但我不会在代码中的任何地方要求它!

任何想法为什么会发生这种情况?

当我修改查询以保留为 QuerySet 并改用 .update() 方法时,该问题似乎消失了...

标签: pythondjango

解决方案


推荐阅读