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 就可以自己正确地跟踪您正在编辑哪个对象。
我有一个名为 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 就可以自己正确地跟踪您正在编辑哪个对象。