I would like to prefetch a model property to a queryset in Django. Is there a way do that ?
Here are the three models:
class Place(models.Model):
name = models.CharField(max_length=200, blank=True)
@property
def bestpicurl(self):
try:
return self.placebestpic.picture.file.url
except:
return None
class PlaceBestPic(models.Model):
place = models.OneToOneField(Place)
picture = models.ForeignKey(Picture, on_delete=models.CASCADE)
class Picture(models.Model):
file = ImageField(max_length=500, upload_to="/images/")
I would need something like:
qs = Place.objects.all().select_related('bestpicurl')
Any clue how to do that ? Thanks!
prefetch_related
and select_related
are instructions that are compiled into the database query/ies. Passing it the name of a pure Python property doesn't work because your database cannot know about them. You would have to select/prefetch the database fields/relations that the property uses under the hood:
qs = Place.objects.select_related('placebestpic')
Now, calling the property will not hit the db:
for p in qs:
# do stuff with p.bestpicurl
Even though you are following a reverse relation here, you do not use prefetch_related
. From the select_related
docs:
You can also refer to the reverse direction of a OneToOneField in the list of fields passed to select_related — that is, you can traverse a OneToOneField back to the object on which the field is defined. Instead of specifying the field name, use the related_name for the field on the related object.