Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Django: while updating record: ValueError: Cannot force an update in save() with no primary key

There are similar issues on SO, but none alike this.

I would like to update a field in a record of a m2m model which has a unique constraint on attendee + training. This model is defined as (model.py):

class Occurrence(models.Model):
    attendee = models.ForeignKey(Attendee, on_delete=models.CASCADE)
    training = models.ForeignKey(Training, on_delete=models.CASCADE)
    attended_date = models.DateField(default=date(1900, 12, 31))

    class Meta:
        constraints = [
            models.UniqueConstraint(fields=['attendee', 'training'], name='unique_attendee_training')
    ]

Now, consider e.g. that John has taken the Python course and already exists as record in the db. If I try get the date of when the training occurred, I would go like this:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

from trainings.models import Attendee, Training, Occurrence
from datetime import date, datetime

attendee = Attendee.objects.get(pk='john@gmail.com')
training = Training.objects.get(pk='python310')
occurrence = Occurrence.objects.get(attendee=attendee, training=training)
print(occurrence.attended_date)
# datetime.date(2021, 11, 4)

However, if I try to update the date of this record, I get the error.

occurrence = Occurrence(attendee=attendee, training=training, attended_date=date(2021, 11, 5))
occurrence.save(update_fields=["attendee", "training", "attended_date"])

The error being:

ValueError: Cannot force an update in save() with no primary key.

How do I update this record?

Note

I believe this should be enough to understand the question. But if you want to reproduce the whole issue, I post here the models (model.py) for Attendees and Trainings.

class Attendee(models.Model):
    first_name = models.CharField('First Name', max_length=30, blank=False)
    last_name = models.CharField('Last Name', max_length=30, blank=False)
    email = models.EmailField("Email Address", max_length=75, blank=False, primary_key=True)

Using email as pk.

class Training(models.Model):
    long_name = models.CharField('Training Name', max_length=80, blank=False, null=False)
    short_name = models.CharField('Abbreviation', max_length=10, blank=False, null=False, primary_key=True)
    description = models.TextField('Descriprion', blank=True)
    alumni = models.ManyToManyField(Attendee, through='Occurrence')

Using short_name as pk. With alumni that relates Attendee and Occurrence.

>Solution :

You are updating the record in the wrong way,


occurrence = Occurrence.objects.get(attendee=attendee, training=training)
print(occurrence.attended_date) # # datetime.date(2021, 11, 4)

# update the record like this
occurrence.attended_date = date(2021, 11, 5)
occurrence.save()

You can tell Django to update specific fields by passing the update_fields parameter, as

# Use instead of `occurrence.save()`
occurrence.save(update_fields=["attended_date"])
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading