Django Model.object.get 预保存函数异常

3 投票
2 回答
2873 浏览
提问于 2025-04-15 11:04

我写了一个函数,用来连接模型的 'pre_save' 信号。在这个函数里,我想检查一下模型实例的主键(pk)是否已经存在于表中,方法是:

sender.objects.get(pk=instance._get_pk_val())

第一次创建这个模型时出现了错误。我捕捉到这个错误,然后根据标题生成了一个 slug 字段。第二次创建实例时就没有抛出错误。我检查了两个实例的 instance._get_pk_val() 的值,它们都是一样的:None

所以:

# This one raises an error in the sluggit function
instance1 = Model(title="title 1")
instance1.save()

# This one doesn't raise an error
instance2 = Model(title="title 2")
instance2.save()

这是我玩 Python 和 Django 的第三天。如果我没看懂什么新手的东西,真抱歉。

编辑:

模型:

class Test(models.Model):
    title = models.CharField(max_length=128)
    slug = models.SlugField(max_length=128)
    slug.prepopulate_from=('title',)

signals.pre_save.connect(package.sluggit, sender=Test)

函数的基本内容:

def sluggit(sender, instance, signal, *args, **kwargs):
    try:
        sender.objects.get(pk=instance._get_pk_val())
    except:
        # Generate Slug Code

@S.Lot 在评论中告诉我可以重写 save() 方法。我得试试这个。不过我还是想知道为什么第二次调用 model.objects.get() 时没有抛出错误。

编辑 2

谢谢 @S.Lot。重写 save 方法效果很好。我还是对信号方法感到好奇。嗯,有点奇怪。

编辑 3

经过更多的尝试,我发现使用 instance.objects.get() 而不是 sender.objects.get() 是有效的:

def sluggit(sender, instance, signal, *args, **kwargs):
    try:
        sender.objects.get(pk=instance._get_pk_val())
    except:
        # Generate Slug Code

应该是:

def sluggit(sender, instance, signal, *args, **kwargs):
    try:
        instance.objects.get(pk=instance._get_pk_val())
    except:
        # Generate Slug Code

这是个bug吗?我之前以为 sender.objects.get() 和 Test.objects.get() 是一样的。

2 个回答

0

谢谢你发这个帖子。现在谷歌搜索的结果(我发这个的时候)有点过时,显示的是连接信号的旧方法(听说最近这个方法已经改写了)。你修改后的内容和正确的代码示例让我明白了怎么做。

我希望更多的人能在他们的评论里加上修正的内容。谢谢你。:-)

1

S.Lott说得对……用save(),因为你已经承认你开始这么做了。

至于信号的问题,我实话实说,我看不出你的代码有什么问题。我自己也在本地运行过,结果是成功的。你确定在提问时描述得准确吗?或者说instance2是不是已经是一个存在的数据库对象(也许是你测试代码中的一个小错误)?

撰写回答