Django - save() update on duplicate key

Viewed 29039

I have little application which allows a user to rate a video.

The user can rate only once. So I have defined the uniqueness on the model.

But he should be able change his rate. So the save() should update on duplicate key

class VideoRate(models.Model):
  """Users can Rate each Video on the criterias defined for the topic"""
  user = models.ForeignKey(User)
  video = models.ForeignKey(VideoFile)
  crit = models.ForeignKey(VideoCrit)
  rate = models.DecimalField(max_digits=2, decimal_places=1, choices=RATE_CHOICES)
  class Meta:
    unique_together = (('user', 'video', 'crit'),)
    verbose_name = 'Video Rating'

If I

rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=2)
rate.save()

It's saving the rating, but if I

rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=3)
rate.save()

I get the normal error

IntegrityError: (1062, "Duplicate entry '1-1-1' for key 'user_id'")

Even if I use force_update=True (since based only on primary keys)

Is there a way to update the rating if it already exists without having to check data before ?

3 Answers

Django 4.1 has added the support for such conflicts. In the backend, it runs a INSERT...ON DUPLICATE KEY UPDATE query.

Example of above in a single query:

rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=2)
rate.save()

# updating rate object if it exists, else create one
rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=3)
VideoRate.objects.bulk_create(
    [rate],
    update_conflicts=True,
    update_fields=['rate']
)
Related