更新对象时出现问题。这是模型:
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字段。因此“if not 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设置为null。其实这很奇怪。我收到一条错误消息+行已更新。
从json数据处理视图中调用第二种方法。但我不认为它与它有任何关系。我想我可以在重置created_by_id时绕过这个问题,但这不是我想要做的,因为它破坏了这个created_by字段的逻辑。
答案 0 :(得分:1)
好吧,问题似乎是您在实例化HourRecord对象时明确设置了id
字段:
hr_object = HourRecord(id=hour_record_pk,...
因此,当您使用save()
方法时,它会检查它是否有ID ...而且确实如此,因此它不会设置who_worked
和created_by
。
我想知道你为什么需要设置ID。通常,您应该让数据库通过自动增量自动设置它。
(与您的问题无关,但您的save
方法应该接受force_update
和force_insert
参数,并将它们传递给super方法。最简单的方法是养成在重写方法时始终使用*args, **kwargs
的习惯。)
编辑:要回答您为什么不能像更新语句那样工作的问题,这是因为您明确地用新对象替换旧对象。实际上,您将删除旧的db条目并插入一组全新的数据。例如,Python无法知道您是否打算保留字段的旧值,或将其设置为NULL。
正如您所指出的,执行此操作的方法是获取现有对象并明确更新其属性。