Python django模型中的一对一关系

Python django模型中的一对一关系,python,django,Python,Django,让我们假设一个城市有多家公司 city1:{ company1: [phone1, email1] company2: [phone1, email2, phone3] } 每个公司可以有一个或多个电话、电子邮件 我想将公司信息存储为 < city1, company1:[phone1, email1] > < city1, company2:[phone1, email2, phone3] > 因为一家公司可以有多个电话或电子邮件,我如何定义这

让我们假设一个城市有多家公司

 city1:{
  company1: [phone1, email1]
  company2: [phone1, email2, phone3]
  }
每个公司可以有一个或多个电话、电子邮件

我想将公司信息存储为

  < city1, company1:[phone1, email1] >
  < city1, company2:[phone1, email2, phone3] >
因为一家公司可以有多个电话或电子邮件,我如何定义这一点?
任何建议

城市
完全相同,可以有多个
公司详细信息
es:将它们放在一个单独的表中

class City(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)


class CompanyDetails(models.Model):
    com_name = models.ForeignKey(City)


class CompanyEmail(models.Model):
    company = models.ForeignKey(CompanyDetails)
    email = models.EmailField(max_length=100, blank=True, null=True)


# And similar for phone numbers

或者,如果您仅使用PostgreSQL,请查看。

问题是如何正确地建模

事实上,这不是一种多对多的关系。这是一种一对多的关系:一个城市可以有零个或多个公司,一个公司可以有零个或多个电子邮件和电话号码

方法一:二对一对多关系 我们可以用四个实体对其进行建模,分别是
城市
公司
公司邮箱
,以及
公司电话
。看起来像这样的东西:

+------+ 1     N +---------+ 1     N +--------------+
| City |---------| Company |---------| CompanyEmail |
+------+         +---------+    |    +--------------+
| name |         | name    |    |    | email        |
+------+         +---------+    |    +--------------+
                                |
                                |  N +--------------+
                                 \---| CompanyPhone |
                                     +--------------+
                                     | phone        |
                                     +--------------+
我们可以将其定义为:

class City(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)

class Company(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    city = models.ForeignKey(City)

class CompanyEmail(models.Model):
    company = models.ForeignKey(Company)
    email = models.EmailField(max_length=100, blank=True, null=True)

class CompanyPhone(models.Model):
    company = models.ForeignKey(Company)
    mobile_number = models.CharField(max_length=10, blank=True, null=True)
然而,这种建模的一个问题是,如果公司有电子邮件地址、电话号码、地址、注册号、商标等,关系的数量可能会变得相当大。因此,模型的数量会急剧增加

然而,优点是我们可以让模型执行自己的检查:
CompanyEmail
可以验证它是否是有效的电子邮件地址,并提供一些方便的方法(例如轻松联系公司)。然而,如果选项的数量很大,那么我们就必须编写少量代码

拔掉公司的连接 我们可以通过在一个抽象模型(例如
CompanyAttribute
)中拉起与公司的关系来缓解这个问题:

或者在Django,这可能看起来像:

class City(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)

class Company(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    city = models.ForeignKey(City)

class AttributeKind(models.Model):
    attributename = models.CharField(max_length=200, blank=True, null=True)

class CompanyAttribute(models.Model):
    company = models.ForeignKey(Company)
    kind = models.ForeignKey(AttributeKind)
    value = models.CharField(max_length=200, blank=True, null=True)
因此,我们可以在默认情况下添加两个
AttributeKind
s:a
phone
email
,但我们可以稍后决定添加更多种类(地址、增值税号码等)


我们现在可以动态地构造新类型的属性。然而,这种方法的一个潜在问题是,很难验证内容是否真正有意义。例如,用户可以将任何字符串存储为电子邮件地址,而强制执行实际的电子邮件地址则比较困难。

这不是多对多;当然,一封电子邮件或一部电话只能属于一家公司。所以它是一对多(从细节到公司的外键)。你使用什么数据库?postgreSql。一家公司可以有多个电话和电子邮件。我们可以减少型号数量,而不是定义四种型号吗?@Prashant:我真的不明白你为什么要减少型号数量。通常情况下,最好在单独的模型中存储单独的实体,而且这样更容易搜索、更新、查询等。我只是想检查一下,这可能吗?Prashant:你可以将整个城市,甚至整个数据库编码为JSON blob,但这会使它难看,无法扩展。
class City(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)


class Company(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    city = models.ForeignKey(City)

class CompanyAttribute(models.Model):
    company = models.ForeignKey(Company)

    class Meta:
        abstract=True

class CompanyEmail(CompanyAttribute):
    email = models.EmailField(max_length=100, blank=True, null=True)

class CompanyPhone(CompanyAttribute):
    mobile_number = models.CharField(max_length=10, blank=True, null=True)
+------+ 1    N +---------+ 1    N +------------------+ N    1 +---------------+
| City |--------| Company |--------| CompanyAttribute |--------| AttributeKind |
+------+        +---------+        +------------------+        +---------------+
| name |        | name    |        | value            |        | attributename |
+------+        +---------+        +------------------+        +---------------+
class City(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)

class Company(models.Model):
    name = models.CharField(max_length=200, blank=True, null=True)
    city = models.ForeignKey(City)

class AttributeKind(models.Model):
    attributename = models.CharField(max_length=200, blank=True, null=True)

class CompanyAttribute(models.Model):
    company = models.ForeignKey(Company)
    kind = models.ForeignKey(AttributeKind)
    value = models.CharField(max_length=200, blank=True, null=True)