Related Name
Django maintains backward relation on each object for easy access to related objects. Suppose you have two models named "School" and "Student" and one school can have multiple students. So you will have model definition something like this
class School(models.Model):
name = models.CharField(max_length=55)
city = models.Charfield(max_length=55)
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School)
Now if you have an school objects then you can access all students of that school with writing query explictly.
school = School.objects.get(id=1)
# Now if need all students of this school, first thing that come in your mind would be
Student.objects.filter(school=school)
# But instead of this, you can access all students by
school.student_set.all()
Here student_set is the default, related name made by Django. But you can have your custom related names like this
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School, related_name='students')
# Now you can do
school.students.all()
Special Character in related name
If you define related_name='+' then backward relation would not be available on object and school.student_set.all() will give you error.
If you’d prefer Django not to create a backwards relation, set related_name to '+' or end it with '+'. For example, this will ensure that the User model won’t have a backwards relation to this model:
Related Query Name
related_query_name is similar to related_name but it gets used in queryset.
If you need to apply some filter on student via school model, then you would do
School.objects.filter(student__name='abc')
But if you define related_query_name then you can do
class Student(models.Model):
name = models.CharField(max_length=55)
school = models.ForeignKey(School, related_query_name='abc')
# Now you can do
School.objects.filter(abc__name='abc')