将基于foreginkey的正则类的实例化约束为正则类和抽象类



我正在创建我的第一个django项目,在创建了模型a之后,我意识到我想创建其他模型B、C。。。它们与A有某些共同的特征,但需要是单独的模型。因此,我创建了一个具有这些特性的抽象类"InteractiableItem"。我希望用户能够喜欢可交互项目,但我也想限制"喜欢"模型的实例化,使每个用户只能喜欢一个给定的可交互项目一次。为了解决这个问题,我尝试创建一个模型。字段"user"one_answers"interactiveitem"之间类似模型中的UniqueConstraint。这给了我以下错误

ERRORS:
feed.Like.interactableitem: (fields.E300) Field defines a relation with model 'InteractableItem', which is either not installed, or is abstract.
feed.Like.interactableitem: (fields.E307) The field feed.Like.interactableitem was declared with a lazy reference to 'feed.interactableitem', but app 'feed' doesn't provide model 'interactableitem'.

我意识到我的错误是通过ForeignKey引用了一个抽象类,然而,如果"用户"喜欢和"可交互项"喜欢不是"喜欢"中的两个字段,我看不出有什么方法可以限制"喜欢"的实例化。这就是我需要帮助的地方。

如何在这样一个"Like"模型上建立实例化约束?

在这里,我提供了我的参考模型:

class InteractableItem(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
date_update = models.DateTimeField(auto_now=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
abstract = True
class Like(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
interactableitem = models.ForeignKey(InteractableItem, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'interactableitem'], name='user_unique_like'),
]

在测试了不同的方法来约束"like"模型的建立后,我意识到有一种方法可以解决这个问题。我让抽象类"BaseItem"具有常规类"interactiveitem"的ForeignKeyLike’现在有一个模型。具有两个ForeignKey字段的Uniqueconstraint到正常类,这是有效的。这样,我只需要确保interactiveitem只创建一次,我相信有更好的方法可以做到这一点,但如果self.pk适用于我能想到的所有场景,因为它在创建之前会检查项目是否在数据库中。

class InteractableItem(models.Model):
pass

class SomeItem(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
date_update = models.DateTimeField(auto_now=True)
interactableitem = models.ForeignKey(InteractableItem, on_delete=models.CASCADE, null=True, blank=True)
author = models.ForeignKey(User, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
abstract = True

def save(self, *args, **kwargs):
if not self.pk:
self.interactableitem = InteractableItem.objects.create()
super(SomeItem, self).save(*args, **kwargs)

class Like(models.Model):
date_created = models.DateTimeField(auto_now_add=True)
user = models.ForeignKey(User, on_delete=models.CASCADE, blank=True)
interactableitem = models.ForeignKey(InteractableItem, on_delete=models.CASCADE, null=True, blank=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['user', 'interactableitem'], name='user_unique_like'),
]

最新更新