Python 使用Django信号后“U保存错误”;save()禁止执行未保存的相关对象以防止数据丢失'';我的模型。”;

Python 使用Django信号后“U保存错误”;save()禁止执行未保存的相关对象以防止数据丢失'';我的模型。”;,python,django,django-models,django-signals,Python,Django,Django Models,Django Signals,Python3.6.5和Django 1.11 伪解释: 两个模型,模型2使用模型1作为外键 模型1的管理员使用模型2的内联 在model1上,我希望获得一个缩短的URL,并在有新条目时将其存储在属性中。要做到这一点,必须保存model1,因为长URL(我要缩短的URL)是基于Autoslug的 Models.py的相关部分 class Model1(models.Model): name = models.CharField(max_length=100) slug = A

Python3.6.5和Django 1.11

伪解释:

  • 两个模型,模型2使用模型1作为外键
  • 模型1的管理员使用模型2的内联
  • 在model1上,我希望获得一个缩短的URL,并在有新条目时将其存储在属性中。要做到这一点,必须保存model1,因为长URL(我要缩短的URL)是基于Autoslug的
Models.py的相关部分

class Model1(models.Model):
    name = models.CharField(max_length=100)
    slug = AutoSlugField(populate_from='name', unique=True,
                     null=True, default=None)


class Model2(models.Model):    
    owner = models.ForeignKey(
        'Model1',
        on_delete=models.CASCADE,
    )
这是我的信号

@receiver(post_save, sender=Model1)
def shorten_url(sender, instance, created, **kwargs):
    if created:
        if not instance.short_url:
            url_short = url_shorten(instance.get_absolute_url())
            instance.short_url = url_short
            post_save.disconnect(shorten_url, sender=sender)
            instance.save()
            post_save.connect(shorten_url, sender=sender)
            return instance
        else:
            post_save.disconnect(shorten_url, sender=sender)
            instance.save()
            post_save.connect(shorten_url, sender=sender)
            return instance
断开连接是为了防止循环,我也不是100%确定它是否正确,但如果没有它,我会看到一次又一次地缩短url的调用

我现在试图解决的问题是我得到了错误
save()禁止在调用save()时将数据丢失到未保存的相关对象“model1”

以下是回溯:

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/exception.py" in inner
41.             response = get_response(request)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/base.py" in _legacy_get_response
249.             response = self._get_response(request)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
187.                 response = self.process_exception_by_middleware(e, request)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/core/handlers/base.py" in _get_response
185.                 response = wrapped_callback(request, *callback_args, **callback_kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in wrapper
551.                 return self.admin_site.admin_view(view)(*args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
149.                     response = view_func(request, *args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/views/decorators/cache.py" in _wrapped_view_func
57.         response = view_func(request, *args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/sites.py" in inner
224.             return view(request, *args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in add_view
1508.         return self.changeform_view(request, None, form_url, extra_context)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapper
67.             return bound_func(*args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/utils/decorators.py" in _wrapped_view
149.                     response = view_func(request, *args, **kwargs)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/utils/decorators.py" in bound_func
63.                 return func.__get__(self, type(self))(*args2, **kwargs2)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in changeform_view
1408.             return self._changeform_view(request, object_id, form_url, extra_context)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in _changeform_view
1449.                 self.save_related(request, form, formsets, not add)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in save_related
1003.             self.save_formset(request, form, formset, change=change)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/contrib/admin/options.py" in save_formset
991.         formset.save()

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/forms/models.py" in save
649.         return self.save_existing_objects(commit) + self.save_new_objects(commit)

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/forms/models.py" in save_new_objects
783.             self.new_objects.append(self.save_new(form, commit=commit))

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/forms/models.py" in save_new
927.             obj.save()

File "/home/username/.virtualenvs/project/lib/python3.6/site-packages/django/db/models/base.py" in save
762.                         "unsaved related object '%s'." % field.name

Exception Type: ValueError at /admin/wa/model1/add/
Exception Value: save() prohibited to prevent data loss due to unsaved related object 'model1'.
我假设这是因为我正在模型1上进行post_save,并且模型2的行正在等待模型1键。错误并不是这样说的。如果错误是model2,那么对我来说更有意义,但事实并非如此

在查看引起错误的base.py行762时,它似乎也在处理未保存(无PK)对象的情况,但再次。。我在这里,不是吗

另一个更新 为了进一步解决这个问题,我提交了在内联表单部分没有数据的管理表单(即Model2中没有数据)。当我这样做时,我在Model1中得到两个条目,每个条目都没有PK。。。PK==无。哇

谢谢你的帮助

为了未来。。。 需要注意的关键点是,当我发现没有生成ID时,如果你点击了,你应该认为。。。最近还有什么变化

在我的例子中,几天前在我的dev box上,我从SQLITE3改为PostgreSQL,希望在生产中也能这样做。然而,我的过程是有缺陷的,所发生的是我有一个完美工作的读取数据库,但没有一个ID是在写入时自动生成的

在我的例子中,我使用PGLOADER加载数据。不要那样做。
使用Django工具转储数据和加载数据

你能添加模型1和模型2的代码并进行完整的回溯吗?@rtindru很好的建议,用这些附加信息编辑了我的问题。错误在表单保存时触发;您添加的代码不包含此表单;你也可以添加它吗?表单是一个基于通用管理模型的表单。没什么特别的。我只是在我的问题中添加了额外的信息。当我在Model2的内联表单中不输入任何值时,它确实保存了,但我得到了两个条目,每个PK==None。所以这很奇怪。如果我是post_save,实例是否应该还没有ID(PK)?当我记录实例时,我看到id==None。奇怪。@rtindru,谢谢你的帮助,我发现我的问题是db问题,见下文。