Django admin 保存对象的副本而不是覆盖

Django admin saves a copy of the object instead of overwrite

我有一个名为 alg_id 的带有 OneToOneFiled 的模型,当我转到管理面板并更改现有对象中的这个文件时,会创建一个新对象,但我想用不同 alg_id。 当我更改其他简单的文本文件时 - 一切正常。 如果我将 alg_id 更改为一个已经存在于数据库中的对象,那么该对象将被覆盖 - 如果我在这里收到警告会更好..

我怎样才能做到这一点?

ps。本项目使用 2.2.6 Django 版本

models.py :

from django.db import models
from django.utils.translation import gettext_lazy as _

class AchievementInfo(models.Model):

    GROUPS = (
        ('Results', 'Results'),
        ('Service', 'Service'),
        ('Team', 'Team'),
        ('Development', 'Development')
    )

    algorithm_id = models.OneToOneField(
        'core.Algorithms',
        models.DO_NOTHING,
        verbose_name=_('Alg id'),
        primary_key=True,
    )
    role_key = models.CharField(_('Role'), max_length=25)
    group = models.CharField(_('Group'), max_length=50, choices=GROUPS)
    name = models.CharField(_('Name'), max_length=100)
    web_name = models.CharField(_('Shown name'), max_length=75)

    class Meta:
        db_table = 'achievements_guide'
        default_permissions = ()
        ordering = ('web_name', 'role_key', 'algorithm_id')
        verbose_name = _('Achievement')
        verbose_name_plural = _('Achievements')

    def __str__(self):
        return f'{self.algorithm_id}: {self.name}, {self.web_name}, {self.role_key}'

admin.py:

from django.contrib import admin
from achievements.models import AchievementInfo

@admin.register(AchievementInfo)
class AchiAdmin(admin.ModelAdmin):
    list_display = ("web_name", "group", "role_key", "algorithm_id")
    list_filter = ("web_name", "role_key")  
    raw_id_fields = ("algorithm_id", )

Django 仅通过 primary_key 跟踪您尝试编辑或添加的对象。如果新设置的主键与数据库中的某个对象匹配,则在保存新创建的对象时替换该对象。同样,如果您更改主键并保存对象,Django 将不会更新旧的,而是创建新的(或替换新匹配的,如果适用)。

由于您将 OneToOneField 用作对象的主键,因此在保存对象时如果没有复杂的附加逻辑,就无法实现您想要实现的目标。

相反,你可以只创建额外的字段作为你的主键(或者让 Django 为你做,而不是在你模型的任何字段中使用 primary_key=True),这样 Django 就可以自己正确地跟踪您正在编辑哪个对象。