Reputation: 419
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.
Upvotes: 2
Views: 646
Reputation: 477814
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',
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
)
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.
Upvotes: 1