Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using related_name correctly in Django

Tags:

python

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.

like image 524
lakshmen Avatar asked Aug 23 '12 08:08

lakshmen


3 Answers

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.

like image 51
sergzach Avatar answered Nov 15 '22 17:11

sergzach


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(...).

like image 44
schacki Avatar answered Nov 15 '22 15:11

schacki


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

like image 1
tstudent Avatar answered Nov 15 '22 17:11

tstudent