Django管理员保存对象的副本,而不是覆盖 [英] Django admin saves a copy of the object instead of overwrite

查看:43
本文介绍了Django管理员保存对象的副本,而不是覆盖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a model with OneToOneFiled named alg_id, and when I go to admin panel and change this filed in existing object, then a new object is created, but I'd like to overwrite same object with different alg_id. When I change other simple text fileds - all works fine. If I change alg_id to one, that already exists in Database, then that object gets overwritten - will be better if I'll get a warning here..

我该如何实现?

ps.该项目使用2.2.6 Django版本

ps. this project use 2.2.6 Django version

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不会更新旧的键,而是创建新的键(或在适用时替换新匹配的键).

Django tracks the object you're trying to edit or add only by a primary_key. If the newly set primary key matches some object in the database, this object will be replaced when saving the newly created object. Similarly, if you change your primary key and save the object, Django will not update the old one, but create the new one (or replace newly matching one, if applicable) instead.

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

As you are using your OneToOneField as a primary key for your object, what you want to achieve is not possible without a complex, additional logic when saving your object.

相反,您可以仅创建其他字段作为您的主键(或者让Django通过在模型的任何字段中不使用 primary_key = True 来为您完成此操作),因此Django可以正常运行自己跟踪要编辑的对象.

Instead, you can just create additional field as your primary key (or let Django do it for you by not using primary_key=True in any of the fields in your model), so Django can properly track by itself which object are you editing.

这篇关于Django管理员保存对象的副本,而不是覆盖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆