Django ModelForm не обновляет экземпляр, а выдает ошибку IntegrityError

У меня какая-то очень странная проблема с ModelForm. Вместо того чтобы сохранить экземпляр, он пытается создать экземпляр с тем же первичным ключом.

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: дублирующееся значение ключа нарушает уникальное ограничение «foundry_upload_pkey» ПОДРОБНОСТИ: Ключ (id)=(1) уже существует.

Я уверен, что это какая-то супертривиальная ошибка, но я просто не могу понять, где я ошибаюсь; имо, это выглядит точно так же, как пример из учебника. upload_form.save() всегда пытается создать запись в базе данных, причем с первичным ключом экземпляра. Я же хочу просто обновить существующий экземпляр (в этом весь смысл ModelForm, не так ли?).

Я удалил таблицу базы данных и миграции и создал их заново, просто чтобы быть уверенным.

Из-за отсутствия контекста я не могу предложить надежное решение, но есть несколько вещей, которые вы можете попробовать для устранения проблемы.

Попробуйте очистить кэш, если есть проблемы с кэшированием или транзакциями, Django может не распознать экземпляр. Убедитесь, что миграции полностью применены, и рассмотрите возможность очистки сессии и перезапуска сервера разработки.

Добавьте отладочный оператор перед вызовом save(), чтобы подтвердить, что upload_form.instance - это действительно тот же объект, а не новый:

print(upload_form.instance.id)

В качестве временного обходного пути можно явно установить первичный ключ

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

В методе save модели использована неправильная/устаревшая сигнатура. Она должна быть такой:

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

Оригинал вызвал фиксацию, когда не должен был, что привело к дублированию первичных ключей.

Вернуться на верх