Django模型中的动态外键链接

flvlnr44  于 2023-06-25  发布在  Go
关注(0)|答案(1)|浏览(124)

我在Django有模特。
其中一个模型的示例可以具有来自同一个表或项目中任何其他表的“父项”,也可以根本没有父项。
如果我将父类作为参数传递给模型类,那么我可以在保存()函数中“处理”父类并在save()中设置外键值吗?
为了澄清,我的问题主要是我不知道父节点的“模型类型”是什么,所以我需要模型在设置ForeignKey值之前确定这一点。
伪代码来解释自己:

model_instance_being_created = ModelType(
    parent = parentinstance
    other_attributes
   )
   model_instance_being_created.save()

在models.py:

class ModelType(models.Model):
    #bunch of attributes 
    parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE)

    def save(self, *args, **kwargs):
        parent_type = self.parent.__class__
        self.parent = parent.objects.get(id=self.parent.id)
    
    super().save(*args, **kwargs)
lymgl2op

lymgl2op1#

你不能有一个动态的外键,因为数据库中的名字被绑定到它是一个键的外表-见文档。
相反,您可以在每个模型类型示例和中间表之间建立一对一的关系,然后将外键作为parent。这看起来确实很笨拙,而且几乎可以肯定有更好的方法基于你的具体情况。

#example model type
class ModelType1(models.Model):
    parent = models.ForeignKey(MidModel, null=True, blank=True, on_delete=models.CASCADE)
    
#use signals to create its midmodel version on creation (need receiver for each model type)
@receiver(post_save, sender=ModelType1)
def ensure_story_stats_exist(**kwargs):
    """Create midmodel if one doesn't exist"""
    if kwargs.get("created", False):
        MidModel.objects.get_or_create(model_type1=kwargs.get("instance"))

#set up your midtable with the kinds of models it can refer to
class MidModel(models.Model)
      model_type1 = models.ForeignKey(ModelType1, null=True, blank=True, on_delete=models.CASCADE, related_name="MT1")
      model_type2 = models.ForeignKey(ModelType2, null=True, blank=True, on_delete=models.CASCADE, related_name="MT2")
     def return_self():
         if self.model_type1:
            return self.model_type1
         
         if self.model_type2:
            return self.model_type2

#get the parent of instance of ModelType1
parent = model_type1.parent.return_self()

相关问题