简体   繁体   中英

How to update a list of objects in Django with a unique constraint?

I am trying to update a list of objects with a unique constraint but an exception is raised. Is it possible deferring a constraint using Django ORM?

This is what I have tried:

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

If get_next_date() is returning dates that already exist then you have a problem that can't be solved.

I assume instead that you want to shift the dates along 'by one episode' ie

episode[0].issue_date --> episode[1].issue_date
episode[1].issue_date --> episode[2].issue_date
episode[2].issue_date --> new date

...which you have tried to do as above but it is failing at the first step because episode[1].issue_date already exists.

To solve this you just need to iterate in reverse order so that:

episode[2].issue_date --> new date
episode[1].issue_date --> previous episode[2].issue_date
episode[0].issue_date --> previous episode[1].issue_date

assuming your get_next_date() function will work under this circumstance you can just change your code to:

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()

This solution is not valid for my problem, because the rearrange is not lineal.

For example:

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

I only see two easy ways to solve the problem, remove the constraint or delete and create the objects using bulk_create

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM