Last active
August 28, 2020 09:27
-
-
Save sks444/102184398eb5d148909285e2c73da3c5 to your computer and use it in GitHub Desktop.
How to effectively design relations between your Django models
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Club(models.Model): | |
name = models.CharField(max_length=100) | |
members = models.ManyToManyField(Member) | |
# Once you have a member it is pretty straightforward to add it to a club: | |
member = Member.objects.get(name='John') | |
club = Club.objects.get(name='sports') | |
club.members.add(member) | |
members = Member.objects.filter(premium=True) | |
club = Club.objects.get(name='premium') | |
club.members.add(*members) | |
# or following is also possible if you have multiple member objects | |
club.members.add(member1, member2, ...) | |
# Similar to add there is remove method to remove a member from a club | |
club.members.remove(member) | |
# or | |
club.members.remove(member1, member2, ...) | |
# You can also get all the members with all: | |
club.members.all() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
reporter = Reporter.objects.get(first_name='John') | |
article = Article.objects.create(headline="This is a test", reporter=reporter) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Article.objects.filter(reporter__first_name='John', reporter__last_name='Smith') | |
# Or you can also use queryset to query certain articles: | |
Article.objects.filter(reporter__in=Reporter.objects.filter(first_name='John')).distinct() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Reporter(models.Model): | |
first_name = models.CharField(max_length=30) | |
last_name = models.CharField(max_length=30) | |
... | |
class Article(models.Model): | |
... | |
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# When Salary has one to one field, we could just create salary | |
# by passing employee instance | |
employee = Employee.objects.get(name='name') | |
Salary.objects.create(price=100.00, employee=employee) | |
# When Employee has one to one field, we can not create salary by | |
# passing an employee instance even if we have related_name defined. | |
# And you have update employee exclusively | |
employee = Employee.objects.get(name='name') | |
salary = Salary.objects.create(price=100.00) | |
employee.salary = salary | |
employee.save() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee(models.Model): | |
--- | |
class Salary(models.Model): | |
employee = models.OneToOneField(Employee, on_delete=models.CASCADE) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee(models.Model): | |
name = models.CharField(max_length=100) | |
pair_progammer = models.OneToOneField('self', null=True, blank=True, on_delete=models.CASCADE, related_name='pair_programmer') |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Employee(models.Model): | |
name = models.CharField(max_length=100) | |
pair_progammer = models.OneToOneField('self', null=True, blank=True, on_delete=models.CASCADE, related_name='pair_programmer') | |
manager = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='employees') | |
# Get the three employees | |
e1 = Employee.objects.get(id=1) | |
e2 = Employee.objects.get(id=2) | |
e3 = Employee.objects.get(id=3) | |
# Assigned e2 as pair programmer of e1 | |
e1.pair_progammer = e2 | |
e1.save() | |
# Assigned e3 as manager of e1 and e2 | |
e1.manager = e3 | |
e1.save() | |
e2.manager = e3 | |
e2.save() | |
# Notice the reverse relationship on manager field allows you get all the employees under a manager, in this case following will give all the employees under e3 manager: | |
employees = e3.employees.all() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
class Salary(models.Model): | |
employee = models.OneToOneField(Employee, on_delete=models.CASCADE, related_name='salary') | |
class Article(models.Model): | |
reporter = models.ForeignKey(Reporter, on_delete=models.CASCADE, related_name='articles') | |
class Club(models.Model): | |
name = models.CharField(max_length=100) | |
members = models.ManyToManyField(Member, related_name='clubs') | |
# OneToOne get salary for an employee using related_name | |
e = Employee.objects.get() | |
salary = e.salary | |
# ForeignKey get articles for a reporter using related_name | |
reporter = Reporter.objects.get() | |
articles = reporter.articles.all() | |
# ManyToMany get all the clubs a member belong to using related_name | |
member = Member.objects.get() | |
clubs = member.clubs.all() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment