Search code examples
pythondjangodjango-modelsforeign-keysdjango-select-related

How to get all related objects in django model ForeignKey and OneToOneField


I'm using django 1.9. I have the following Django models:

@python_2_unicode_compatible
class Projects(models.Model):
    index = models.IntegerField(blank=True,default=1)
    year = models.CharField(max_length=255, blank=True)
    title = models.CharField(max_length=255, blank=True)
    description = models.TextField(blank=True)

    def __str__(self):
        return  '%s, %s, %s, %s' %(self.index,self.year,self.title,
               self.description)
@python_2_unicode_compatible
class Awards(models.Model):
    title = models.CharField(max_length=255, blank=True)

    def __str__(self):
        return '%s' %( self.title)


@python_2_unicode_compatible
class Images(models.Model):
    projects = models.ForeignKey(Projects,null=True,blank=True, related_name='images_projects')
    awards =  models.OneToOneField(Awards,null=True,blank=True,related_name='images_awards')
    title = models.CharField(max_length=255, blank=True)
    file = models.ImageField(upload_to='upload_images/')
    uploaded_at = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return '%s, %s' %(self.file, self.pk)

1)I'm trying to get all the model objects Projects and model objects Images that are related to the model Projects Projects.objects.all().select_related('images_projects') As a result, I get only model objects Projects.

2) I want to get all the objects of the model Awards and associated fields in the Images.

 Awards.objects.all().prefetch_related('images_awards')

As a result, I receive only all fields of the Award model.

How to get related fields together with all objects of the main model in my 2 cases?


Solution

  • select_related and prefetch_related are performance boosters that retrieve the related objects for the current lookup. The query returns the corresponding objects (primarily) for the lookup, and then the related objects are fetched alongside;

    You still need to use the regular syntax for accessing the related object in Python.

    e.g.

    for p in Projects.objects.all().select_related('images_projects'):
        print(p.images_projects)
    

    No database trips will be made for accessing p.images_projects since it was already fetched alongside the project.