Django ModelForm doesn't update instance but fails with IntegrityError

I'm having some really weird issue with a ModelForm. Instead of saving the instance, it attempts to create the instance with the same primary key.

class Upload(models.Model):
    file = models.FileField(upload_to=get_foundry_upload_name, null=False, blank=False)
    filename = models.CharField(max_length=256, null=True, blank=True)

    foundry = models.ForeignKey(Foundry, on_delete=models.CASCADE)

    family = models.CharField(max_length=256, null=True, blank=True)
    family_select = models.ForeignKey(Family, null=True, blank=True, on_delete=models.CASCADE)

    style = models.CharField(max_length=256, null=True, blank=True)
    style_select = models.ForeignKey(Style, null=True, blank=True, on_delete=models.CASCADE)

    processed = models.BooleanField(default=False)
    created = models.DateTimeField("Created", auto_now_add=True)


class UploadProcessForm(ModelForm):
    class Meta:
        model = Upload
        fields = (
            "filename",
            "family",
            "family_select",
            "style",
            "style_select",
        )


def upload_process_row(request, foundry, id):
    
    i = get_object_or_404(Upload, id=id, foundry=foundry)
    upload_form = UploadProcessForm(instance=i)

    if request.method == "POST":
        upload_form = UploadProcessForm(request.POST, instance=i)
        if upload_form.is_valid():
            upload_form.save()
    
    return render(request, "foundry/upload_process.row.html", {
        "f": upload_form
    })

django.db.utils.IntegrityError: duplicate key value violates unique constraint "foundry_upload_pkey" DETAIL: Key (id)=(1) already exists.

I'm certain this is some super trivial mistake, but I just cannot spot where I'm going wrong; imo this looks exactly like the textbook example. The upload_form.save() always attempts to create a database entry, and with the instance's primary key. I'd just want to update the existing instance (that's the whole point of a ModelForm, no?).

I've wiped the database table and migrations and recreated them fresh, just to be sure.

Due to lack of context I couldn't provide the solid solution but there are few things you can try for dubugging the issue.

Try clearing the cache if there’s any caching or transaction issues, Django might not recognize the instance. Ensure that migrations are fully applied, and consider clearing the session and restarting the development server.

Add a debugging statement before the save() call to confirm that upload_form.instance is indeed the same object and not a new one:

print(upload_form.instance.id)

You can explicitly set primary key as temporary workaround

if upload_form.is_valid():
obj = upload_form.save(commit=False)
obj.id = i.id  # explicitly set the id to the existing instance's id (not very good practice)
obj.save()

The model's save method used an wrong/outdated signature. It should be:

def save(self, **kwargs):
        self.filename = self.file.name
        super().save(**kwargs)

The original triggered the the commit when it should not, thus resulting in duplicate primary keys.

Back to Top