假设我已经创建了一个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
的情况下,有一个副本。但如何找出哪一个?
当您将模型实例化为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,
)
在这个例子中,a
和b
必须匹配,但c
不必。
您已经定义了使用您唯一且唯一的组合键使模型“重复”的原因,因此您应该通知您的.get_duplicates()
函数。