Python 如何建模m2m关系,其中相关表可以是城市、地区(州)或国家

Python 如何建模m2m关系,其中相关表可以是城市、地区(州)或国家,python,django,Python,Django,在Django,我有以下模型: class Artist(models.Model): name = models.CharField(max_length=128) born_place = models.ForeignKey(???) dead_place = models.ForeignKey(???) live_places = models.ManyToManyField(???) work_places = models.ManyToManyF

在Django,我有以下模型:

class Artist(models.Model):
    name = models.CharField(max_length=128)
    born_place = models.ForeignKey(???)
    dead_place = models.ForeignKey(???)
    live_places = models.ManyToManyField(???)
    work_places = models.ManyToManyField(???)

class Country(models.Model):
    iso = models.CharField(max_length=2, primary_key=True)
    name = models.CharField(max_length=50)

class Region(models.Model):
    iso = models.CharField(max_length=2, blank=True)
    name = models.CharField(max_length=150)
    country = models.ForeignKey('Country')

class City(models.Model):
    name = models.CharField(max_length=150)
    region = models.ForeignKey('Region')
所有地方(
出生地
死亡地
居住地
工作地
)都可以是
城市
地区
国家
。而
城市
必须有
地区
,而
地区
必须有
国家

我怎样才能做到这一点

所有的地方(出生地、死亡地、生活地、工作地)可以是一个城市、一个地区或一个国家

在这种情况下,您需要的是一个。在Django中,这可以通过方便的框架实现

从文件中:

设置GenericForeignKey有三个部分:

  • 为您的模型提供ContentType的ForeignKey

  • 为您的模型提供一个字段,该字段可以存储您将要关联的模型中的主键值。(对于大多数模型,这意味着一个IntegerField或PositiveIntegerField。)此字段的类型必须与泛型关系中涉及的模型主键的类型相同。例如,如果使用IntegerField,则无法与使用CharField作为主键的模型形成泛型关系

  • 为您的模型提供一个GenericForeignKey,并将上述两个字段的名称传递给它。如果这些字段名为“content\u type”和“object\u id”,则可以忽略这一点——这是GenericForeignKey将查找的默认字段名

  • 所有的地方(出生地、死亡地、生活地、工作地)可以是一个城市、一个地区或一个国家

    在这种情况下,您需要的是一个。在Django中,这可以通过方便的框架实现

    从文件中:

    设置GenericForeignKey有三个部分:

  • 为您的模型提供ContentType的ForeignKey

  • 为您的模型提供一个字段,该字段可以存储您将要关联的模型中的主键值。(对于大多数模型,这意味着一个IntegerField或PositiveIntegerField。)此字段的类型必须与泛型关系中涉及的模型主键的类型相同。例如,如果使用IntegerField,则无法与使用CharField作为主键的模型形成泛型关系

  • 为您的模型提供一个GenericForeignKey,并将上述两个字段的名称传递给它。如果这些字段名为“content\u type”和“object\u id”,则可以忽略这一点——这是GenericForeignKey将查找的默认字段名


  • 看一看Django的泛型关系和,它可以让您为各种类型的对象设置关键点,而不仅仅是一个特定的对象

    看看Django的泛型关系和,它可以让您为各种类型的对象设置关键点,而不仅仅是一个特定的对象

    嗯。。是的,也许你可以使用一般关系。但是我认为你可以通过跳出框框来解决一些问题

    我想说,你可以创建一个区域模型,而不是国家、地区和城市;然后使用

    这将为您的领土创建一个层次结构,因此现在您可以使用任意多的分区(例如,大陆、行星、社区),并且您不必更改您的模型。至于艺术家,你可以做如下事情:

    class Artist(models.Model):
        name = models.CharField(max_length=128)
        born_place = models.ForeignKey(Territory)
        dead_place = models.ForeignKey(Territory)
        live_places = models.ManyToManyField(Territory)
        work_places = models.ManyToManyField(Territory)
    

    所以现在。。。出生地可以是一个城市,一个地区,一个星球。。。你要什么都行!我想那是你的问题。我不是django方面的专家,这只是解决O.O.P.中此类问题的一种通用方法。。是的,也许你可以使用一般关系。但是我认为你可以通过跳出框框来解决一些问题

    我想说,你可以创建一个区域模型,而不是国家、地区和城市;然后使用

    这将为您的领土创建一个层次结构,因此现在您可以使用任意多的分区(例如,大陆、行星、社区),并且您不必更改您的模型。至于艺术家,你可以做如下事情:

    class Artist(models.Model):
        name = models.CharField(max_length=128)
        born_place = models.ForeignKey(Territory)
        dead_place = models.ForeignKey(Territory)
        live_places = models.ManyToManyField(Territory)
        work_places = models.ManyToManyField(Territory)
    

    所以现在。。。出生地可以是一个城市,一个地区,一个星球。。。你要什么都行!我想那是你的问题。我不是django方面的专家,这只是解决O.O.P中此类问题的一般方法。

    您也可以使用模型继承

    class Territory(models.Model):
        name = models.CharField(max_length=150)
    
    class Country(Territory):
        iso = models.CharField(max_length=2, primary_key=True)
    
    class Region(Territory):
        iso = models.CharField(max_length=2, blank=True)
        country = models.ForeignKey('Country')
    
    class City(Territory):
        region = models.ForeignKey('Region')
    
    class Artist(models.Model):
        name = models.CharField(max_length=128)
        born_place = models.ForeignKey(Territory)
        dead_place = models.ForeignKey(Territory)
        live_places = models.ManyToManyField(Territory)
        work_places = models.ManyToManyField(Territory)
    

    致以最良好的祝愿

    您还可以使用模型继承

    class Territory(models.Model):
        name = models.CharField(max_length=150)
    
    class Country(Territory):
        iso = models.CharField(max_length=2, primary_key=True)
    
    class Region(Territory):
        iso = models.CharField(max_length=2, blank=True)
        country = models.ForeignKey('Country')
    
    class City(Territory):
        region = models.ForeignKey('Region')
    
    class Artist(models.Model):
        name = models.CharField(max_length=128)
        born_place = models.ForeignKey(Territory)
        dead_place = models.ForeignKey(Territory)
        live_places = models.ManyToManyField(Territory)
        work_places = models.ManyToManyField(Territory)
    

    致以最良好的祝愿

    嗯,很有趣的方法。我需要玩一下这个,看看所有的含义(管理,表结构等)。嗯,有趣的方法。我需要玩一下这个,看看所有的影响(管理,表结构等)。在我发布我的问题后,我想到了这个解决方案。在我的版本中唯一的区别是我在Territory类中有一个“种类”字段(具有可能值的choices字段:country、region、city)。这样,我可以只过滤城市或国家等。更重要的是,我可以限制城市的父级应该是一个地区,而地区的父级应该是一个国家。目前,这是我最喜欢的解决方案。但是我需要评估另外两个解决方案,泛型关系和模型继承。哦,是的!我忘记了“种类”字段,我通常称之为“类型”。。使用继承的缺点是,如果您想引入新的“类型”或“种类”,就必须修改代码,这就是为什么当您拥有一定数量的元素时,继承是一个很好的解决方案。。女巫可能是你的情况。。。在处理更动态创建的“类别”和“子类别”时,我经常使用此解决方案。在python中,我通常使用“种类”而不是“类型”,以避免出现问题,因为“类型”在python中是一个关键字。但我同意“类型”是一个更好的定义。谢谢你告诉我继承和你的解决方案之间的区别。你对通用汽车有什么意见吗