如何在Django中更新具有唯一约束的对象列表?
我正在尝试更新一个有唯一约束的对象列表,但出现了异常。请问在使用Django的ORM时,有办法延迟约束的检查吗?
这是我尝试过的:
class Episode(models.Model):
issue_date = models.DateTimeField(db_index=True, unique=True)
...
def rearrange_episodes(cls, programme, after):
next_episodes = Episode.objects.filter(programme=programme, issue_date__gte=after).order_by('issue_date')
for episode in next_episodes:
episode.issue_date = get_next_date()
episode.save() #Crash -> Duplicate entry
2 个回答
0
这个解决方案对我的问题不适用,因为重新排列的方式不是线性的。
举个例子:
episode[4].issue_date --> new date
episode[3].issue_date --> previous episode[4].issue_date
episode[2].issue_date --> not change
episode[1].issue_date --> previous episode[0].issue_date
episode[0].issue_date --> new date
我只想到两种简单的方法来解决这个问题,要么去掉限制,要么使用 bulk_create 删除并重新创建对象。
1
如果 get_next_date()
函数返回的日期已经存在,那你就遇到了一个无法解决的问题。
我假设你想要的是把日期往后推一个“集数”,也就是说:
episode[0].issue_date --> episode[1].issue_date
episode[1].issue_date --> episode[2].issue_date
episode[2].issue_date --> new date
...你已经尝试这样做了,但在第一步就失败了,因为 episode[1].issue_date
已经存在。
要解决这个问题,你只需要反向遍历,这样:
episode[2].issue_date --> new date
episode[1].issue_date --> previous episode[2].issue_date
episode[0].issue_date --> previous episode[1].issue_date
假设你的 get_next_date()
函数在这种情况下可以正常工作,你只需要把代码改成:
def rearrange_episodes(cls, programme, after):
next_episodes = Episode.objects.filter(programme=programme, issue_date__gte=after).order_by('-issue_date')
for episode in next_episodes:
episode.issue_date = get_next_date()
episode.save()