Django-guardar() actualizar en clave duplicada
save unique-constraint (2)
Tengo una pequeña aplicación que permite a un usuario calificar un video.
El usuario puede puntuar solo una vez. Así que he definido la singularidad en el modelo.
Pero él debería poder cambiar su ritmo. Así que el save()
debería actualizarse en clave duplicada
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''
Si yo
rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=2)
rate.save()
Está guardando la calificación, pero si yo
rate = VideoRate(user_id=1, video_id=1, crit_id=1, rate=3)
rate.save()
Me sale el error normal
IntegrityError: (1062, "Duplicate entry ''1-1-1'' for key ''user_id''")
Incluso si uso force_update=True
(ya que solo se basa en claves primarias)
¿Hay alguna manera de actualizar la calificación si ya existe sin tener que verificar los datos antes?
En primer lugar, debe comprobar si existe la calificación. Por lo tanto, puede usar lo que Daniel Roseman dijo o el uso existe , pero no puede resolverlo con una simple actualización ya que la actualización no crea nuevos registros ...
rating = 2
rate, created = VideoRate.objects.get_or_create(user_id=1, video_id=1, crit_id=1,
defaults={''rate'':rating})#if create, also save the rate infdormation
if not created:# update
rate.rate = rating
rate.save()
Puede usar los valores predeterminados para pasar argumentos exrta, por lo que si se trata de una inserción , se creará un registro de la base de datos con toda la información requerida y no es necesario actualizarlo nuevamente ...
Actualización: esta respuesta es bastante antigua como la pregunta. Como mencionó @peterthomassen, Django ahora tiene el método update_or_create()
Para actualizar una calificación existente, debe tener la que desea actualizar. Si sabe que el objeto no existe, use get_or_create
:
rate, created = VideoRate.objects.get_or_create(user_id=1, video_id=1, crit_id=1)
rate.rate = 2
rate.save()
Puedes acortar el proceso usando update()
:
VideoRate.objects.filter(user_id=1, video_id=1, crit_id=1).update(rate=2)
Pero esto fallará silenciosamente si la clasificación no existe, no creará una.