Skip to content

Instantly share code, notes, and snippets.

@sks444
Last active August 28, 2020 09:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sks444/102184398eb5d148909285e2c73da3c5 to your computer and use it in GitHub Desktop.
Save sks444/102184398eb5d148909285e2c73da3c5 to your computer and use it in GitHub Desktop.
How to effectively design relations between your Django models
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()
reporter = Reporter.objects.get(first_name='John')
article = Article.objects.create(headline="This is a test", reporter=reporter)
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()
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)
# 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()
class Employee(models.Model):
---
class Salary(models.Model):
employee = models.OneToOneField(Employee, on_delete=models.CASCADE)
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')
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()
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