简体   繁体   中英

Best approach to use Many to Many in Django + SQL

I am making a web app and i wish to use many to many fields in models.I haven't given much thought before and have simply used many to many field in models but now i am thinking how actually these many to many are stored in database and what would be the best approach when using Many to Many Fields in Models.

Approach 1:

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)

OR Approach 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)

Do both methods handle many to many fields in the same way ?

I am using MySQL as Database

Update "To make them Equivalent, Second Approach should have field as ForiegnKey and not many to many " also to avoid multiple company admin entries Field company should be one to one.

Solution

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 will construct a model that has two ForeignKey s, one to the Company and one to the User model. This model thus corresponds to the junction table [wiki] between the Company and User model.

A ManyToManyField thus does not map on a column . The ManyToManyField is more a concept that enables one to write simpler queries, and provides a more convenient interface.

Do both methods handle many to many fields in the same way ?

No . With the latter you will make two extra tables, one for the CompanyAdmin model, and one for the ManyToManyField between CompanyAdmin and User . It would also result in more JOIN s to fetch the companies for which a User is an admin for example, and it would here be possible to construct multiple CompanyAdmin s for the same Company , and thus linking the same User multiple times.

You can define however custom attributes in the junction table, by specifying the junction model explicitly with the through=… parameter [Django-doc] :

from django.conf import settings

class Company(models.Model):
    admin = models.ManyToManyField(
        settings.AUTH_USER_MODEL,
        related_name='org_admin',
        
    )
    created_on = models.DateTimeField(auto_now_add=True)
    updated_on = models.DateTimeField(auto_now=True)

class (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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM