在 Django + SQL 中使用多对多的最佳方法
Best approach to use Many to Many in Django + SQL
我正在制作一个网络应用程序,我希望在 models.I 中使用多对多字段,之前没有考虑太多,只是在模型中使用多对多字段,但现在我在想实际上如何这些多对多存储在数据库中,在模型中使用多对多字段时最好的方法是什么。
方法一:
class Company(models.Model):
name = models.CharField(max_length = 190,blank = False,null = False)
about = models.CharField(max_length = 260,blank = False,null = True)
website = models.URLField(blank = False)
address = models.OneToOneField(Address,related_name="org_address",on_delete=models.SET_NULL,null=True)
admin = models.ManyToManyField(User,related_name="org_admin",blank = False)
created_on = models.DateTimeField(default = timezone.now)
updated_on = models.DateTimeField(default = timezone.now)
或
方法二:
class Company(models.Model):
name = models.CharField(max_length = 190,blank = False,null = False)
about = models.CharField(max_length = 260,blank = False,null = True)
website = models.URLField(blank = False)
address = models.OneToOneField(Address,related_name="org_address",on_delete=models.SET_NULL,null=True)
created_on = models.DateTimeField(default = timezone.now)
updated_on = models.DateTimeField(default = timezone.now)
class CompanyAdmin(models.Model):
admin = models.ManyToManyField(User,related_name="org_admin",blank = False)
company = models.ForeignKey(Company,related_name="company",on_delete=models.CASCADE)
这两种方法是否以相同的方式处理多对多字段?
我正在使用 MySQL 作为数据库
更新
“为了使它们等效,第二种方法的字段应为 ForiegnKey 而不是 多对多 ”
还要避免多个公司管理员条目 Field company 应该是一对一的。
解决方案
Do not create join tables as Django ORM Handles this itself.
but now I am thinking how actually these many to many are stored in database.
Django 将构造一个具有两个 ForeignKey
的模型,一个给 Company
一个给 User
模型。因此,该模型对应于 Company
和 User
模型之间的 junction table [wiki]。
A ManyToManyField
因此不会映射到 列 。 ManyToManyField
更多的是一种概念,可以让人们编写更简单的查询,并提供更方便的界面。
Do both methods handle many to many fields in the same way ?
否。对于后者,您将制作 两个 额外的 table,一个用于 CompanyAdmin
模型,一个用于 CompanyAdmin
之间的 ManyToManyField
和 User
。它还会导致更多的 JOIN
s 来获取 User
是其管理员的公司,并且在这里可以构建 multiple CompanyAdmin
s 用于相同的 Company
,因此多次链接相同的 User
。
您可以在联结 table 中定义自定义属性,方法是使用 through=…
parameter [Django-doc]:
显式指定联结模型
from django.conf import settings
class Company(models.Model):
admin = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='org_admin',
<b>through='CompanyAdmin'</b>
)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
class <b>CompanyAdmin</b>(models.Model):
admin = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
company = models.ForeignKey(
Company,
on_delete=models.CASCADE
)
Note: It is normally better to make use of the settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use the User
model [Django-doc] directly. For more information you can see the referencing the User
model section of the documentation.
Note: Django's DateTimeField
[Django-doc]
has a auto_now_add=…
parameter [Django-doc]
to work with timestamps. This will automatically assign the current datetime
when creating the object, and mark it as non-editable (editable=False
), such
that it does not appear in ModelForm
s by default.
我正在制作一个网络应用程序,我希望在 models.I 中使用多对多字段,之前没有考虑太多,只是在模型中使用多对多字段,但现在我在想实际上如何这些多对多存储在数据库中,在模型中使用多对多字段时最好的方法是什么。
方法一:
class Company(models.Model):
name = models.CharField(max_length = 190,blank = False,null = False)
about = models.CharField(max_length = 260,blank = False,null = True)
website = models.URLField(blank = False)
address = models.OneToOneField(Address,related_name="org_address",on_delete=models.SET_NULL,null=True)
admin = models.ManyToManyField(User,related_name="org_admin",blank = False)
created_on = models.DateTimeField(default = timezone.now)
updated_on = models.DateTimeField(default = timezone.now)
或 方法二:
class Company(models.Model):
name = models.CharField(max_length = 190,blank = False,null = False)
about = models.CharField(max_length = 260,blank = False,null = True)
website = models.URLField(blank = False)
address = models.OneToOneField(Address,related_name="org_address",on_delete=models.SET_NULL,null=True)
created_on = models.DateTimeField(default = timezone.now)
updated_on = models.DateTimeField(default = timezone.now)
class CompanyAdmin(models.Model):
admin = models.ManyToManyField(User,related_name="org_admin",blank = False)
company = models.ForeignKey(Company,related_name="company",on_delete=models.CASCADE)
这两种方法是否以相同的方式处理多对多字段?
我正在使用 MySQL 作为数据库
更新 “为了使它们等效,第二种方法的字段应为 ForiegnKey 而不是 多对多 ” 还要避免多个公司管理员条目 Field company 应该是一对一的。
解决方案
Do not create join tables as Django ORM Handles this itself.
but now I am thinking how actually these many to many are stored in database.
Django 将构造一个具有两个 ForeignKey
的模型,一个给 Company
一个给 User
模型。因此,该模型对应于 Company
和 User
模型之间的 junction table [wiki]。
A ManyToManyField
因此不会映射到 列 。 ManyToManyField
更多的是一种概念,可以让人们编写更简单的查询,并提供更方便的界面。
Do both methods handle many to many fields in the same way ?
否。对于后者,您将制作 两个 额外的 table,一个用于 CompanyAdmin
模型,一个用于 CompanyAdmin
之间的 ManyToManyField
和 User
。它还会导致更多的 JOIN
s 来获取 User
是其管理员的公司,并且在这里可以构建 multiple CompanyAdmin
s 用于相同的 Company
,因此多次链接相同的 User
。
您可以在联结 table 中定义自定义属性,方法是使用 through=…
parameter [Django-doc]:
from django.conf import settings
class Company(models.Model):
admin = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='org_admin',
<b>through='CompanyAdmin'</b>
)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
class <b>CompanyAdmin</b>(models.Model):
admin = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
company = models.ForeignKey(
Company,
on_delete=models.CASCADE
)
Note: It is normally better to make use of the
settings.AUTH_USER_MODEL
[Django-doc] to refer to the user model, than to use theUser
model [Django-doc] directly. For more information you can see the referencing theUser
model section of the documentation.
Note: Django's
DateTimeField
[Django-doc] has aauto_now_add=…
parameter [Django-doc] to work with timestamps. This will automatically assign the current datetime when creating the object, and mark it as non-editable (editable=False
), such that it does not appear inModelForm
s by default.