【问题标题】:django update - update logic of already set mandatory fieldsdjango update - 已设置必填字段的更新逻辑
【发布时间】:2010-01-21 11:42:53
【问题描述】:

我在更新对象时遇到问题。这是模型:

class HourRecord(models.Model):
    day_of_work = models.PositiveIntegerField(max_length=1)
    date_of_work = models.DateField(verbose_name='creation date')
    who_worked = models.ForeignKey(User)
    project = models.ForeignKey(Project, related_name='hour_record_set', null=True)

    created_by = models.ForeignKey(User, editable=False, related_name='hour_record_creator')
    created = models.DateTimeField(auto_now_add=True, editable=False, verbose_name='creation date')
    modified_by = models.ForeignKey(User, editable=False, related_name='hour_record_modifier')
    modified = models.DateTimeField(auto_now=True, editable=False)


    def save(self, request):
        if not self.id:
            self.who_worked = request.user
            self.created_by = request.user
        self.modified_by = request.user
        super(HourRecord, self).save()

created_by 字段只有在它是一个新对象时才应该设置。因此“如果不是 self.id:”。到目前为止,这工作得很好。

到目前为止,我更新了这样的对象:

if hrform.is_valid():
            hour_record = hrform.save(commit=False)
            hour_record.save(request)

但是当我像这样更新模型时出现错误:

project = Project.objects.get(id=project_pk)
hr_object = HourRecord(id=hour_record_pk, day_of_work=weekday, date_of_work=date, who_worked=request.user, project=project)
hr_object.save(request)

错误信息是:

Column 'created_by_id' cannot be null

这对我来说很奇怪,因为 created_by 列已经设置好了。我在数据库中检查了它。在我再次检查此错误消息后,对象已更新并且 created_by_id 设置为空。其实这很奇怪。我收到一条错误消息 + 行已更新。

第二种方法是从 json 数据处理视图中调用的。但我不认为这与它有任何关系。我想我可以在重置 created_by_id 时绕过这个问题,但这不是我想要做的,因为它破坏了这个 created_by 字段的逻辑。

【问题讨论】:

    标签: django django-models


    【解决方案1】:

    好吧,问题似乎是您在实例化 HourRecord 对象时明确设置了 id 字段:

    hr_object = HourRecord(id=hour_record_pk,...
    

    因此,当您使用 save() 方法时,它会检查它是否有 ID...并且确实有,因此它不会设置 who_workedcreated_by

    我想知道您为什么需要设置 ID。通常,您应该让数据库通过自动增量自动设置它。

    (与您的问题无关,但您的save 方法应该接受force_updateforce_insert 参数,并将它们传递给super 方法。最简单的方法是养成始终覆盖方法时使用*args, **kwargs。)

    编辑:要回答为什么这不像更新语句那样工作的问题,这是因为您明确地用新对象替换旧对象。实际上,您正在删除旧的数据库条目并插入一组全新的数据。例如,Python 无法知道您是打算保留字段的旧值还是将其设置为 NULL。

    正如您所指出的,这样做的方法是获取现有对象并显式更新其属性。

    【讨论】:

    • 我想更新/覆盖对象。因此,我将 ID 提供给模型构造函数。这是错误的方法吗?我正在遵循 django 文档的方法:docs.djangoproject.com/en/dev/ref/models/instances/…
    • 没关系,但在这种情况下,您还需要在实例化对象时自动设置created_by,因为在您的save 方法中不会这样做。
    • 好的,但我只是想知道为什么它的行为不像 sql update 语句。我也不是 sql 专家,但我认为 update 语句只更新提供的字段,而让其他字段保持原样。这就是我所期望的。没有与此行为等效的 django 吗?
    • 我想我只需要获取 HourRecord 对象,然后使用 HourRecord.get_object_or_404(pk=hour_record_pk) 修改我想要修改的值,然后更改字段然后保存。这样我想我解决了我的问题。但我仍然希望 HourRecord(id=hour_record_pk,..) 表现不同。但可能有充分的理由表明它的行为不符合我的预期;-)
    猜你喜欢
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    • 2023-04-05
    • 2020-10-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    相关资源
    最近更新 更多