lakshmen
lakshmen

Reputation: 29094

Using related_name correctly in Django

I have two models that are related together using ForeignKey and related_name is used. Here is an example.

class Student(models.Model):
    name = models.CharField(max_length=255)
    birthday = models.DateField(blank=True)


class Class(models.Model):

    name = models.CharField(max_length=255)
    student = models.ForeignKey(Student,
                                related_name='classes',
                                null=True)

    def __unicode__(self):
        return self.name

For example, I would like to access the class name.

This is what i tried.

john = Student.objects.get(username = 'john')
print john.classes.name

nothing's get printed.

But when i try john.classes

i get django.db.models.fields.related.RelatedManager object at 0x109911410. This is shows that they are related. But i would like to get the class name.

Am i doing something wrong? How do i access the name of the class using related_name? Need some guidance.

Upvotes: 23

Views: 26579

Answers (3)

sergzach
sergzach

Reputation: 6764

Yes, classes is a manager. It can be several classes for one teacher. So to output their names you should do:

john = Student.objects.get(username='john')
for class2 in john.classes.all():
   print class2.name

If you want only one class for one student then use one-to-one relation. In this case you can access the related field with your method.

Upvotes: 24

tstudent
tstudent

Reputation: 89

you can do like this to access the first row in the table

john = Student.objects.get(username = 'john')    
john.classes.all().first().name # to access first row
john.classes.all().last().name # to access last row

in the above example you don't want to iterate over the objects

it will give you the name of the class in the first row

Upvotes: 1

schacki
schacki

Reputation: 9533

Just be aware: you are defining a 1-many relationship. Thus, student could have multiple classes, therefore john.classes.name cannot work, since you have not specified the class of which you want to have the name. in john.classes "classes" is just a manager that you can use like any other Django Model Manager. You can do a john.classes.all() (like sergzach propsed), but also things like john.classes.get(...) or john.classes.filter(...).

Upvotes: 3

Related Questions