[英]Best approach to use Many to Many in Django + SQL
我正在制作一個網絡應用程序,我希望在模型中使用多對多字段。我之前沒有考慮太多,只是在模型中使用了多對多字段,但現在我在想這些多對多實際上是如何存儲的數據庫以及在模型中使用多對多字段時的最佳方法是什么。
方法一:
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)
或 方法 2:
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而不是多對多”也為了避免多個公司管理員條目字段公司應該是一對一的。
解決方案
不要創建連接表,因為 Django ORM 會自行處理。
但現在我在想這些多對多實際上是如何存儲在數據庫中的。
Django 將構建一個具有兩個ForeignKey
的模型,一個是Company
模型,一個是User
模型。 因此,該模型對應於Company
和User
模型之間的連接表[wiki] 。
因此, ManyToManyField
不會映射到列上。 ManyToManyField
更像是一個概念,它使人們能夠編寫更簡單的查詢,並提供更方便的界面。
這兩種方法是否以相同的方式處理多對多字段?
沒有。 對於后者,您將創建兩個額外的表,一個用於CompanyAdmin
模型,另一個用於CompanyAdmin
和User
之間的ManyToManyField
。 例如,這也會導致更多JOIN
來獲取User
作為管理員的公司,並且在這里可以為同一個Company
構造多個CompanyAdmin
,從而多次鏈接同一個User
。
但是,您可以通過使用through=…
參數 [Django-doc]顯式指定連接模型,在連接表中定義自定義屬性:
from django.conf import settings
class Company(models.Model):
admin = models.ManyToManyField(
settings.AUTH_USER_MODEL,
related_name='org_admin',
through='CompanyAdmin'
)
created_on = models.DateTimeField(auto_now_add=True)
updated_on = models.DateTimeField(auto_now=True)
class CompanyAdmin(models.Model):
admin = models.ForeignKey(
settings.AUTH_USER_MODEL,
on_delete=models.CASCADE
)
company = models.ForeignKey(
Company,
on_delete=models.CASCADE
)
注意:通常最好使用
settings.AUTH_USER_MODEL
[Django-doc]來引用用戶模型,而不是直接使用User
模型 [Django-doc] 。 有關更多信息,您可以查看文檔的引用User
模型部分。
注意:Django 的
DateTimeField
[Django-doc]有一個auto_now_add=…
參數 [Django-doc]來處理時間戳。 這將在創建對象時自動分配當前日期時間,並將其標記為不可編輯(editable=False
),這樣默認情況下它不會出現在ModelForm
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.