如何在Django中保存重复的实例?

问题描述 投票:0回答:1

假设我已经创建了一个Django模型的实例。我想获得另一个在数据库中重复的实例。有没有通用的方法来做到这一点,而没有找出哪个唯一索引负责这种重复:

class MyModel(models.Model):
    ...

instance = MyModel(...)
print(instance.id)  # None

...

duplicate = get_duplicate(instance)  # what should I type here instead of get_duplicate?
print(duplicate.id)  # Some ID in DB

我希望函数get_duplicate不依赖于模型的内部结构。另外我不想修改模型。

例如,如果我需要找出重复的存在,我可以做instance.save()。在IntegrityError的情况下,有一个副本。但如何找出哪一个?

python django
1个回答
1
投票

当您将模型实例化为MyModel(...)时,您将获得未保存的实例。要将它传播到数据库,你必须在它上面调用.save(),此时instance.id将被设置为某个东西。您也可以将MyModel.objects.create(...)作为捷径。

现在,回答这个问题,复制数据库中已有的记录;将它的id设置为None,并再次保存。

instance = MyModel.objects.get(id=1)
instance.id = None
instance.save()
print(instance.id)  # 2

如果我正确理解你的问题,你想要.save()创建两个数据库行而不是一个?我不明白为什么你想要它,或者你如何使它变得有用,但是你可以通过在模型上覆盖.save()来实现:

class MyModel(models.Model):
    ...

    def save(self, *args, **kwargs):
        instance = super().save(*args, **kwargs)

        instance.id = None
        instance.save()

        return instance

至于找到重复的实例,这要困难得多。您将不得不决定使实例成为“重复”的原因。例如,如果它是用户模型,也许只有电子邮件地址是相同的,它是重复的,但如果它是一个事务实例,那么每个字段必须是相同的。

由于这与模型的类型密不可分,因此您需要将其放在模型本身上。我将在下面写一个玩具示例:

class MyModel(models.Model):
    a = models.CharField(unique=True, ...)
    b = models.CharField(unique=True, ...)
    c = models.CharField(...)

    def get_duplicates(self):
        return type(self).filter(
            a=self.a,
            b=self.b,
        )

在这个例子中,ab必须匹配,但c不必。

您已经定义了使用您唯一且唯一的组合键使模型“重复”的原因,因此您应该通知您的.get_duplicates()函数。

© www.soinside.com 2019 - 2024. All rights reserved.