簡體   English   中英

在 Django + SQL 中使用多對多的最佳方法

[英]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模型。 因此,該模型對應於CompanyUser模型之間的連接表[wiki]

因此, ManyToManyField不會映射到列上 ManyToManyField更像是一個概念,它使人們能夠編寫更簡單的查詢,並提供更方便的界面。

這兩種方法是否以相同的方式處理多對多字段?

沒有 對於后者,您將創建兩個額外的表,一個用於CompanyAdmin模型,另一個用於CompanyAdminUser之間的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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM