Opened 47 minutes ago
#37201 new Bug
Prefetch with to_attr silently ignored if matching property exists
| Reported by: | dc-strahlkraft | Owned by: | |
|---|---|---|---|
| Component: | Database layer (models, ORM) | Version: | 6.0 |
| Severity: | Normal | Keywords: | |
| Cc: | Triage Stage: | Unreviewed | |
| Has patch: | no | Needs documentation: | no |
| Needs tests: | no | Patch needs improvement: | no |
| Easy pickings: | no | UI/UX: | no |
Description
Minimal reproduction https://gitlab.com/Dan_Strahlkraft/django-prefetch
Given these models:
class Product(models.Model):
@property
def enabled_images(self):
return self.images.filter(enabled=True)
class ProductImage(models.Model):
product = models.ForeignKey(Product, models.PROTECT, related_name="images")
enabled = models.BooleanField()
I want to eagerly load the enabled_images property so that it doesn't hit the database on access. So I write: Product.objects.prefetch_related(Prefetch("images", ProductImage.objects.filter(enabled=True), to_attr="enabled_images")). But that doesn't prefetch anything. The Prefetch is silently ignored.
The simplest workaround I can think of is:
class Product(models.Model):
@property
def enabled_images(self):
try:
return self.prefetched_enabled_images
except AttributeError:
return self.images.filter(enabled=True)
Then I can write Product.objects.prefetch_related(Prefetch("images", ProductImage.objects.filter(enabled=True), to_attr="prefetched_enabled_images")) and now accessing product.enabled_images won't hit the database, but I think it's uglier.