Django admin save_model 没有在 Postgres 中推进主键
Posted
技术标签:
【中文标题】Django admin save_model 没有在 Postgres 中推进主键【英文标题】:Django admin save_model not advancing primary key in Postgres 【发布时间】:2020-02-18 08:58:00 【问题描述】:所以我在 Django 管理员中有一个函数允许我在数据库中创建一个重复的MyModel
:
def save_model(self, request, obj, form, change):
if '_saveasnew' in request.POST:
old_obj_id = resolve(request.path).args[0]
old_obj = MyModel.objects.get(id=old_obj_id)
obj.other_id = old_obj.other_id
obj.status = old_obj.status
obj.project_id = old_obj.project_id
obj.test_url = old_obj.test_url
obj.save()
super(MyModelAdmin, self).save_model(request, obj, form, change)
这个创建工作正常,但是我有另一个系统与这个数据库交互,每次调用这个函数时都会看到插入失败。例如,如果我以这种方式在 Django admin 中创建 2 个重复条目,那么另一个系统将看到两个错误,例如
IntegrityError 重复键值违反唯一约束“my_model_pkey”详细信息:键 (id)=(1234) 已存在。
我正在使用 Django 1.11.15 和 PostgreSQL 9.5.15。
【问题讨论】:
你运行的是什么版本的 Django?请注意,随着版本号的增加,Django 放弃了对旧 PostgreSQL 版本的支持。请参阅docs.djangoproject.com/en/2.1/releases/2.1/… 或任何其他相关版本。 @GjertG 添加了使用的版本。 两个应用程序是否使用相同的版本?我假设“另一个系统”是指一个单独的 Django 应用程序?我的猜测是在指向正确的对象方面存在问题。 传递给函数的参数到底是什么?对 obj 参数最感兴趣。 本例中的“其他系统”只是直接的SQL插入语句。save_model
函数是 Django ModelAdmin 类中的一个被覆盖的函数 (docs)
【参考方案1】:
我最好的猜测是,您的代码在某处告诉您的数据库创建一个新的对象行并将该行的 ID 显式设置为 X。实际上,代码应该告诉您的数据库创建一个新的对象行并隐式地将该行的 ID 设置为下一个可用整数。
您的代码令人困惑,因为您正在以非常复杂的方式进行操作。为什么这个函数同时接受一个对象和一个请求?然后它从请求中找到旧对象?新对象是在哪里创建的?
一种更简单的方法是首先检查您是否要另存为新的。如果没有,请使用更新对象并为其提供现有对象的功能。如果是另存为新请求,则创建一个与现有对象具有相似值的新对象行(ID 除外)。然后使用更改更新该新对象。或者你的逻辑应该有效。无论如何,如果您考虑一下步骤的顺序,有一种更直接的方法可以完成您希望发生的步骤。
【讨论】:
您能否编写而不是描述您的“更简单方式”的代码?以上是关于Django admin save_model 没有在 Postgres 中推进主键的主要内容,如果未能解决你的问题,请参考以下文章
Django admin save_model 没有在 Postgres 中推进主键
覆盖 Django InlineModelAdmin 上的 save_model
为啥 save_model 方法在 admin.StackedInline 中不起作用?