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:aphone
和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)